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.

Carga

local funcs = require("funcs")

call

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ámetro Tipo Descripción
target string ID de función en formato "namespace:name"
...args any Argumentos 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.

async

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ámetro Tipo Descripción
target string ID de función en formato "namespace:name"
...args any Argumentos pasados a la función

Devuelve: Future, error

new

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, error

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.

with_context

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ámetro Tipo Descripción
values table Pares clave-valor para agregar al contexto

Devuelve: Executor, error

with_actor

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ámetro Tipo Descripción
actor Actor Actor de seguridad (del módulo security)

Devuelve: Executor, error

with_scope

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ámetro Tipo Descripción
scope Scope Alcance de seguridad (del módulo security)

Devuelve: Executor, error

with_options

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ámetro Tipo Descripción
options table Opciones especificas de implementacion

Devuelve: Executor, error

call / async

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")

Future

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

response / channel

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

is_complete

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

is_canceled

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

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

Devuelve: boolean

result

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

error

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

cancel

Cancela la operación asincrona.

future:cancel()

Operaciones Paralelas

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

Permisos

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

Accion Recurso Descripción
funcs.call ID de Función Llamar una función especifica
funcs.context context Usar with_context() para establecer contexto personalizado
funcs.security security Usar with_actor() o with_scope()

Errores

Condición Tipo Reintentable
Target vacio errors.INVALID no
Namespace faltante errors.INVALID no
Nombre faltante errors.INVALID no
Permiso denegado errors.PERMISSION_DENIED no
Suscripcion fallida errors.INTERNAL no
Error de función varia varia

Consulte Manejo de Errores para trabajar con errores.