Invocacion de Funciones
Invocacion de Funciones
Sección titulada «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, errendprint(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.
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 bloquearlocal future, err = funcs.async("app.process:analyze_data", large_dataset)if err then return nil, errend
-- Hacer otro trabajo mientras el computo se ejecuta...
-- Esperar resultado cuando este listolocal 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
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
Executor
Sección titulada «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
Sección titulada «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 downstreamlocal 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
Sección titulada «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 usuariolocal 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
Sección titulada «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
Sección titulada «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 externalocal exec = funcs.new():with_options({timeout = 5000})local result, err = exec:call("app.external:fetch_data", query)if err then -- Manejar timeout u otro errorend| Parámetro | Tipo | Descripción |
|---|---|---|
options | table | Opciones especificas de implementacion |
Devuelve: Executor, error
call / async
Sección titulada «call / async»Versiones de Executor de call y async que usan el contexto configurado.
-- Construir executor reutilizable con contextolocal exec = funcs.new() :with_context({trace_id = "abc-123"}) :with_options({timeout = 10000})
-- Hacer multiples llamadas con mismo contextolocal 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.
response / channel
Sección titulada «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
Sección titulada «is_complete»Verificacion no bloqueante si el future ha completado.
while not future:is_complete() do -- hacer otro trabajo time.sleep("100ms")endlocal result, err = future:result()Devuelve: boolean
is_canceled
Sección titulada «is_canceled»Devuelve true si cancel() fue llamado en este future.
if future:is_canceled() then print("Operation was canceled")endDevuelve: 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())endDevuelve: 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())endDevuelve: error|nil, boolean
Cancela la operación asincrona.
future:cancel()Devuelve: boolean, error
Operaciones Paralelas
Sección titulada «Operaciones Paralelas»Ejecutar multiples operaciones concurrentemente usando async y channel.select.
-- Iniciar multiples operaciones en paralelolocal 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 canaleslocal 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() endendPermisos
Sección titulada «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
Sección titulada «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.