Unidades de Computação
O Wippy fornece três formas de executar código: funções, processos e workflows. Elas compartilham os mesmos mecanismos subjacentes, mas diferem no tempo de vida, no destino do estado e no que acontece quando ocorrem falhas.
Funções
Funções executam quando são chamadas e retornam um resultado. Trate cada chamada como stateless: o estado durável ou compartilhado deve residir em um banco de dados ou store. Pools de funções podem reutilizar estados Lua; portanto, globais de módulo e upvalues de closures são locais ao worker e não formam um store confiável entre chamadas.
local funcs = require("funcs")
local result, err = funcs.call("app.math:add", 2, 3)
if err then
return nil, err
end
Funções executam no contexto do chamador. Se ele for cancelado ou encerrar, as chamadas de função em execução também serão canceladas.
Processos
Processos são atores. Eles mantêm estado entre várias mensagens, executam independentemente de quem os iniciou e se comunicam por passagem de mensagens.
local pid, err = process.spawn("app.workers:handler", "app:processes")
if err then return nil, err end
local ok, send_err = process.send(pid, "job", {task = "process_data"})
if send_err then return nil, send_err end
return ok
Depois de iniciado, um processo executa independentemente do código que o criou. Processos podem monitorar ou vincular-se uns aos outros e participar de árvores de supervisão que reiniciam filhos que falharam.
O scheduler multiplexa milhares de processos em um pool de workers. Cada processo cede a execução enquanto aguarda I/O, permitindo que outros executem.
Workflows
Workflows destinam-se a operações duráveis que precisam se recuperar de interrupções. Um provedor de workflow, como o Temporal, registra o histórico de execução e o reproduz para reconstruir o estado após crashes, reinicializações ou mudanças de infraestrutura.
-- The provider records this workflow so a worker restart can replay it.
local pid, err = process.spawn("app.orders:process", "app:temporal_worker", order_id)
if err then return nil, err end
return pid
A durabilidade acrescenta latência porque as operações do workflow são registradas. Use workflows quando a recuperação for mais importante do que a latência menor de funções ou processos, como em processos de negócio com várias etapas e orquestrações de longa duração.
Comparação
| Funções | Processos | Workflows | |
|---|---|---|---|
| Estado | Local à chamada; não dependa do reúso de workers | Em memória | Reconstruído a partir do histórico persistido |
| Tempo de vida | Uma chamada | Até encerrar ou falhar | Persiste entre reinicializações |
| Comunicação | Valor de retorno + mensagens | Passagem de mensagens | Chamadas de atividades + mensagens |
| Tratamento de falhas | O chamador trata | Árvores de supervisão | Recuperação pelo provedor; retries seguem a política |
| Latência | Mais baixa | Baixa | Mais alta |
Mesmo código, comportamento diferente
Muitos módulos se adaptam automaticamente ao contexto. Por exemplo, time.sleep() cede a execução tanto em funções quanto em processos, permitindo que outros trabalhos executem; em um workflow, o provedor também registra o timer para que o replay não inicie um segundo timer.