Pular para o conteúdo

Invocação de Funções

A forma principal de chamar outras funções no Wippy. Execute funções registradas síncronamente ou assíncronamente entre processos, com suporte completo para propagação de contexto, credenciais de segurança e timeouts. Este módulo é central para construir aplicações distribuídas onde componentes precisam comunicar.

local funcs = require("funcs")

Chama uma função registrada síncronamente. Use quando precisar de um resultado imediato e puder aguardar por ele.

local result, err = funcs.call("app.api:get_user", user_id)
if err then
return nil, err
end
print(result.name)
ParâmetroTipoDescrição
targetstringID da função no formato “namespace:name”
...argsanyArgumentos passados para a função

Retorna: result, error

A string target segue o padrão namespace:name onde namespace identifica o módulo e name identifica a função específica.

Inicia uma chamada de função assíncrona e retorna imediatamente com um Future. Use para operações de longa duração onde você não quer bloquear, ou quando quer executar múltiplas operações em paralelo.

-- Iniciar computação pesada sem bloquear
local future, err = funcs.async("app.process:analyze_data", large_dataset)
if err then
return nil, err
end
-- Fazer outro trabalho enquanto computação executa...
-- Aguardar resultado quando pronto
local ch = future:response()
local payload, ok = ch:receive()
if ok then
local result = payload:data()
end
ParâmetroTipoDescrição
targetstringID da função no formato “namespace:name”
...argsanyArgumentos passados para a função

Retorna: Future, error

Cria um novo Executor para construir chamadas de função com contexto customizado. Use quando precisar propagar contexto de requisição, definir credenciais de segurança ou configurar timeouts.

local exec = funcs.new()

Retorna: Executor

Builder para chamadas de função com opções de contexto customizado. Métodos retornam novas instâncias de Executor (encadeamento imutável), então você pode reutilizar uma configuração base.

Adiciona valores de contexto que estarão disponíveis para a função chamada. Use para propagar dados com escopo de requisição como trace IDs, sessões de usuário ou feature flags.

-- Propagar contexto de requisição para serviços 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âmetroTipoDescrição
valuestablePares chave-valor para adicionar ao contexto

Retorna: Executor, error

Define o ator de segurança para verificações de autorização na função chamada. Use ao chamar uma função em nome de um usuário específico.

local security = require("security")
local actor = security.actor() -- Obter ator do usuário atual
-- Chamar função admin com credenciais do usuário
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âmetroTipoDescrição
actorActorAtor de segurança (do módulo security)

Retorna: Executor, error

Define o escopo de segurança para funções chamadas. Escopos definem as permissões disponíveis para a chamada.

local security = require("security")
local scope = security.new_scope()
local exec = funcs.new():with_scope(scope)
ParâmetroTipoDescrição
scopeScopeEscopo de segurança (do módulo security)

Retorna: Executor, error

Define opções de chamada como timeout e prioridade. Use para operações que precisam de limites de tempo.

-- Definir timeout de 5 segundos para chamada de API externa
local exec = funcs.new():with_options({timeout = 5000})
local result, err = exec:call("app.external:fetch_data", query)
if err then
-- Tratar timeout ou outro erro
end
ParâmetroTipoDescrição
optionstableOpções específicas da implementação

Retorna: Executor, error

Versões Executor de call e async que usam o contexto configurado.

-- Construir executor reutilizável com contexto
local exec = funcs.new()
:with_context({trace_id = "abc-123"})
:with_options({timeout = 10000})
-- Fazer multiplas chamadas com mesmo contexto
local users, _ = exec:call("app.api:list_users")
local posts, _ = exec:call("app.api:list_posts")

Retornado por chamadas async(). Representa uma operação assíncrona em andamento.

Retorna o channel subjacente para receber o resultado.

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

Retorna: Channel

Verificação não-bloqueante se o future completou.

while not future:is_complete() do
-- fazer outro trabalho
time.sleep("100ms")
end
local result, err = future:result()

Retorna: boolean

Retorna true se cancel() foi chamado neste future.

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

Retorna: boolean

Retorna o resultado em cache se completo, ou nil se ainda pendente.

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

Retorna: Payload|nil, error|nil

Retorna o erro se o future falhou.

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

Retorna: error|nil, boolean

Cancela a operação assíncrona.

future:cancel()

Retorna: boolean, error

Execute múltiplas operações concorrentemente usando async e channel.select.

-- Iniciar múltiplas operações em 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)
-- Aguardar todas completarem usando channels
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

Operações de função estão sujeitas a avaliação de política de segurança.

AçãoRecursoDescrição
funcs.callID da FunçãoChamar uma função específica
funcs.contextcontextUsar with_context() para definir contexto customizado
funcs.securitysecurityUsar with_actor() ou with_scope()
CondiçãoTipoRetentável
Target vazioerrors.INVALIDnão
Namespace ausenteerrors.INVALIDnão
Nome ausenteerrors.INVALIDnão
Permissão negadaerrors.PERMISSION_DENIEDnão
Falha de inscriçãoerrors.INTERNALnão
Erro da funçãovariavaria

Veja Error Handling para trabalhar com erros.