Ir al contenido

Invocacion de Funciones

La forma principal de llamar otras funciones en Wippy. Ejecutar funciones registradas sincrona o asincronamente entre procesos, con soporte completo para propagacion de contexto, credenciales de seguridad y tiempos de espera. Este módulo es central para construir aplicaciones distribuidas donde los componentes necesitan comunicarse.

local funcs = require("funcs")

Llama una función registrada sincronamente. Use esto cuando necesite un resultado inmediato y pueda esperarlo.

local result, err = funcs.call("app.api:get_user", user_id)
if err then
return nil, err
end
print(result.name)
ParámetroTipoDescripción
targetstringID de función en formato “namespace:name”
...argsanyArgumentos pasados a la función

Devuelve: result, error

El string target sigue el patrón namespace:name donde namespace identifica el módulo y name identifica la función especifica.

Inicia una llamada de función asincrona y devuelve inmediatamente con un Future. Use esto para operaciones de larga duración donde no quiere bloquear, o cuando quiere ejecutar multiples operaciones en paralelo.

-- Iniciar computo pesado sin bloquear
local future, err = funcs.async("app.process:analyze_data", large_dataset)
if err then
return nil, err
end
-- Hacer otro trabajo mientras el computo se ejecuta...
-- Esperar resultado cuando este listo
local ch = future:response()
local payload, ok = ch:receive()
if ok then
local result = payload:data()
end
ParámetroTipoDescripción
targetstringID de función en formato “namespace:name”
...argsanyArgumentos pasados a la función

Devuelve: Future, error

Crea un nuevo Executor para construir llamadas de función con contexto personalizado. Use esto cuando necesite propagar contexto de solicitud, establecer credenciales de seguridad o configurar tiempos de espera.

local exec = funcs.new()

Devuelve: Executor

Constructor para llamadas de función con opciones de contexto personalizado. Los metodos devuelven nuevas instancias de Executor (encadenamiento inmutable), por lo que puede reutilizar una configuración base.

Agrega valores de contexto que estaran disponibles para la función llamada. Use esto para propagar datos con alcance de solicitud como IDs de traza, sesiones de usuario o banderas de caracteristicas.

-- Propagar contexto de solicitud a servicios downstream
local exec = funcs.new():with_context({
request_id = ctx.get("request_id"),
feature_flags = {dark_mode = true}
})
local user, err = exec:call("app.api:get_user", user_id)
ParámetroTipoDescripción
valuestablePares clave-valor para agregar al contexto

Devuelve: Executor, error

Establece el actor de seguridad para verificaciones de autorizacion en la función llamada. Use esto cuando llame una función en nombre de un usuario específico.

local security = require("security")
local actor = security.actor() -- Obtener actor del usuario actual
-- Llamar función admin con credenciales del usuario
local exec = funcs.new():with_actor(actor)
local result, err = exec:call("app.admin:delete_record", record_id)
if err and err:kind() == "PERMISSION_DENIED" then
return nil, errors.new("PERMISSION_DENIED", "User cannot delete records")
end
ParámetroTipoDescripción
actorActorActor de seguridad (del módulo security)

Devuelve: Executor, error

Establece el alcance de seguridad para funciones llamadas. Los alcances definen los permisos disponibles para la llamada.

local security = require("security")
local scope = security.new_scope()
local exec = funcs.new():with_scope(scope)
ParámetroTipoDescripción
scopeScopeAlcance de seguridad (del módulo security)

Devuelve: Executor, error

Establece opciones de llamada como tiempo de espera y prioridad. Use esto para operaciones que necesitan limites de tiempo.

-- Establecer tiempo de espera de 5 segundos para llamada API externa
local exec = funcs.new():with_options({timeout = 5000})
local result, err = exec:call("app.external:fetch_data", query)
if err then
-- Manejar timeout u otro error
end
ParámetroTipoDescripción
optionstableOpciones especificas de implementacion

Devuelve: Executor, error

Versiones de Executor de call y async que usan el contexto configurado.

-- Construir executor reutilizable con contexto
local exec = funcs.new()
:with_context({trace_id = "abc-123"})
:with_options({timeout = 10000})
-- Hacer multiples llamadas con mismo contexto
local users, _ = exec:call("app.api:list_users")
local posts, _ = exec:call("app.api:list_posts")

Devuelto por llamadas async(). Representa una operación asincrona en progreso.

Devuelve el canal subyacente para recibir el resultado.

local future, _ = funcs.async("app.api:slow_operation", data)
local ch = future:response() -- o future:channel()
local result = channel.select {
ch:case_receive(),
timeout:case_receive()
}

Devuelve: Channel

Verificacion no bloqueante si el future ha completado.

while not future:is_complete() do
-- hacer otro trabajo
time.sleep("100ms")
end
local result, err = future:result()

Devuelve: boolean

Devuelve true si cancel() fue llamado en este future.

if future:is_canceled() then
print("Operation was canceled")
end

Devuelve: boolean

Devuelve el resultado cacheado si esta completo, o nil si aun esta pendiente.

local value, err = future:result()
if err then
print("Failed:", err:message())
elseif value then
print("Got:", value:data())
end

Devuelve: Payload|nil, error|nil

Devuelve el error si el future fallo.

local err, has_error = future:error()
if has_error then
print("Error kind:", err:kind())
end

Devuelve: error|nil, boolean

Cancela la operación asincrona.

future:cancel()

Devuelve: boolean, error

Ejecutar multiples operaciones concurrentemente usando async y channel.select.

-- Iniciar multiples operaciones en paralelo
local f1, _ = funcs.async("app.api:get_user", user_id)
local f2, _ = funcs.async("app.api:get_orders", user_id)
local f3, _ = funcs.async("app.api:get_preferences", user_id)
-- Esperar que todas completen usando canales
local user_ch = f1:channel()
local orders_ch = f2:channel()
local prefs_ch = f3:channel()
local results = {}
for i = 1, 3 do
local r = channel.select {
user_ch:case_receive(),
orders_ch:case_receive(),
prefs_ch:case_receive()
}
if r.channel == user_ch then
results.user = r.value:data()
elseif r.channel == orders_ch then
results.orders = r.value:data()
else
results.prefs = r.value:data()
end
end

Las operaciones de función estan sujetas a evaluacion de politica de seguridad.

AccionRecursoDescripción
funcs.callID de FunciónLlamar una función especifica
funcs.contextcontextUsar with_context() para establecer contexto personalizado
funcs.securitysecurityUsar with_actor() o with_scope()
CondiciónTipoReintentable
Target vacioerrors.INVALIDno
Namespace faltanteerrors.INVALIDno
Nombre faltanteerrors.INVALIDno
Permiso denegadoerrors.PERMISSION_DENIEDno
Suscripcion fallidaerrors.INTERNALno
Error de funciónvariavaria

Consulte Manejo de Errores para trabajar con errores.