Ir al contenido

Gestión de Procesos

Crear, monitorear y comunicarse con procesos hijos. Implementa patrones de modelo de actores con paso de mensajes, supervisión y gestión de ciclo de vida.

La variable global process siempre está disponible — no requiere require() ni necesita aparecer en modules:.

Obtener el ID del frame actual o el ID del proceso:

local frame_id = process.id() -- Identificador de cadena de llamadas
local pid = process.pid() -- ID del proceso

Enviar mensaje(s) a un proceso por PID o nombre registrado:

local ok, err = process.send(destination, topic, ...)
ParámetroTipoDescripción
destinationstringPID o nombre registrado
topicstringNombre del tema (no puede comenzar con @)
...anyValores del payload

Permiso: process.send sobre el PID destino

-- Lanzamiento básico
local pid, err = process.spawn(id, host, ...)
-- Con monitoreo (recibir eventos EXIT)
local pid, err = process.spawn_monitored(id, host, ...)
-- Con enlace (recibir LINK_DOWN en salida anormal)
local pid, err = process.spawn_linked(id, host, ...)
-- Enlazado y monitorizado
local pid, err = process.spawn_linked_monitored(id, host, ...)
ParámetroTipoDescripción
idstringID de fuente del proceso (ej., "app.workers:handler")
hoststringID del host (ej., "app:processes")
...anyArgumentos pasados al proceso lanzado

Permisos:

  • process.spawn sobre el id del proceso
  • process.host sobre el id del host
  • process.spawn.monitored sobre el id del proceso (para variantes monitorizadas)
  • process.spawn.linked sobre el id del proceso (para variantes enlazadas)
-- Terminar forzosamente un proceso
local ok, err = process.terminate(destination)
-- Solicitar cancelación controlada con un motivo opcional
local ok, err = process.cancel(destination, "shutting down")
ParámetroTipoDescripción
destinationstringPID o nombre registrado
reasonstringMotivo opcional entregado al destino

Permisos: process.terminate, process.cancel sobre el PID destino

Monitorear o enlazar a un proceso existente:

-- Monitoreo: recibir eventos EXIT cuando el destino sale
local ok, err = process.monitor(destination)
local ok, err = process.unmonitor(destination)
-- Enlace: bidireccional, recibir LINK_DOWN en salida anormal
local ok, err = process.link(destination)
local ok, err = process.unlink(destination)

Permisos: process.monitor, process.unmonitor, process.link, process.unlink sobre el PID destino

local options = process.get_options()
local ok, err = process.set_options({trap_links = true})
CampoTipoDescripción
trap_linksbooleanSi los eventos LINK_DOWN se entregan al canal de eventos

Obtener canales para recibir mensajes y eventos de ciclo de vida:

local inbox = process.inbox() -- Objetos Message del tema @inbox
local events = process.events() -- Eventos de ciclo de vida del tema @events
ConstanteDescripción
process.event.CANCELCancelación solicitada
process.event.EXITProceso monitorizado ha salido
process.event.LINK_DOWNProceso enlazado terminó de forma anormal
CampoTipoDescripción
kindstringConstante del tipo de evento
fromstringPID de origen
resultanyPara EXIT: el valor devuelto (presente en salida normal)
erroranyPara EXIT: el error (presente en salida anormal)
reasonstringPara CANCEL: por qué se está cancelando el proceso

Suscribirse a temas personalizados:

local ch = process.listen(topic, options)
process.unlisten(ch)
ParámetroTipoDescripción
topicstringNombre del tema (no puede comenzar con @)
options.messagebooleanSi es true, recibir objetos Message; si es false, payloads raw

Al recibir del buzón o con {message = true}:

local msg = inbox:receive()
msg:topic() -- string: nombre del tema
msg:from() -- string|nil: PID del remitente
msg:payload() -- Payload: wrapper (llamar :data() para extraer)
msg:payload():data() -- any: valor actual del payload

Lanzar un proceso, esperar su resultado y devolver:

local result, err = process.exec(id, host, ...)

Permisos: process.exec sobre el id del proceso, process.host sobre el id del host

Actualizar el proceso actual a una nueva definición preservando el PID:

-- Actualizar a nueva versión, pasando estado
process.upgrade(id, ...)
-- Mantener la misma definición, re-ejecutar con nuevo estado
process.upgrade(nil, preserved_state)

Crear un spawner con contexto personalizado para procesos hijos:

local spawner = process.with_context({request_id = "123"})

Permiso: process.context sobre “context”

process.with_options(options) crea un spawner que lleva opciones de spawn (ej., un selector de red) en lugar de valores de contexto:

local spawner = process.with_options({network = "app:tor_proxy"})
OpciónTipoDescripción
networkstringID de registro de una entrada network.* a usar para las conexiones salientes del hijo

Permiso: process.context sobre “context”; seleccionar una red adicionalmente requiere network.select sobre ese ID de red.

SpawnBuilder es inmutable — cada método devuelve una nueva instancia:

spawner:with_context(values) -- Añadir valores de contexto
spawner:with_actor(actor) -- Establecer actor de seguridad
spawner:with_scope(scope) -- Establecer ámbito de seguridad
spawner:with_name(name) -- Establecer nombre del proceso
spawner:with_message(topic, ...) -- Encolar mensaje a enviar tras el spawn
spawner:with_options(options) -- Fusionar opciones de spawn (ej., network)

Permiso: process.security sobre “security” para :with_actor() y :with_scope()

spawner:spawn(id, host, ...)
spawner:spawn_monitored(id, host, ...)
spawner:spawn_linked(id, host, ...)
spawner:spawn_linked_monitored(id, host, ...)

Mismos permisos que las funciones de spawn a nivel de módulo.

Registrar un proceso bajo un nombre y alcanzarlo por ese nombre en lugar de su PID. Cualquier función que acepte un destination (send, terminate, cancel, monitor, link, …) acepta un nombre registrado en lugar de un PID.

local ok, err = process.registry.register(name) -- self, ámbito local
local pid, err = process.registry.lookup(name)
local ok, err = process.registry.unregister(name)

El argumento opcional scope selecciona la garantía de consistencia del nombre. Por defecto es LOCAL. Los cuatro ámbitos y sus garantías se describen en la Guía de Cluster; en resumen:

ConstanteVisibilidadGarantía
process.registry.LOCALsolo este nodoInstantáneo, local al nodo
process.registry.EVENTUALen todo el clusterEventualmente consistente (gossip)
process.registry.CONSISTENTen todo el clusterSingleton linealizable (Raft)
process.registry.STRONGen todo el clusterConsistente + cada nodo activo reconoce

En un nodo independiente solo LOCAL es significativo; los ámbitos de cluster requieren clustering.

local ok, err = process.registry.register(name, pid, scope)
ParámetroTipoRequeridoPor defectoDescripción
namestringNombre a registrar
pidstringnoselfPID a registrar; por defecto el proceso que llama
scopenumbernoLOCALUna de las constantes de ámbito anteriores

Devuelve true en éxito, o nil, error en fallo. Los conflictos (nombre ya registrado a un PID diferente bajo un ámbito de cluster) devuelven errors.ALREADY_EXISTS. Registrar el mismo nombre al mismo PID es idempotente. Un registro STRONG bloquea hasta que cada nodo activo reconoce o el plazo de reserva expira; en tiempo de espera devuelve un error.

Registrar en nombre de un PID diferente requiere adicionalmente el permiso process.registry.foreign sobre el PID destino.

local pid, err = process.registry.lookup(name)

Devuelve el string de PID registrado, o nil, error con tipo errors.NOT_FOUND cuando el nombre no está registrado.

local ok, err = process.registry.unregister(name, scope)

scope por defecto es LOCAL y debe coincidir con el ámbito bajo el que se registró el nombre. Para CONSISTENT y STRONG, el proceso propietario es el único autorizado a desregistrar; desregistrar un nombre propiedad de otro PID devuelve false. Los nombres también se liberan automáticamente cuando el proceso propietario sale (y, para ámbitos de cluster, cuando su nodo se va), por lo que el desregistro explícito es para liberación anticipada.

Los permisos controlan lo que puede hacer un proceso que llama. Todas las comprobaciones usan el contexto de seguridad (actor) del que llama contra el recurso destino.

Las políticas pueden permitir/denegar basándose en:

  • Actor: El principal de seguridad que hace la solicitud
  • Acción: La operación que se realiza (ej., process.send)
  • Recurso: El destino (PID, id de proceso, id de host, o nombre)
  • Atributos: Contexto adicional incluyendo pid (ID del proceso que llama)
PermisoFuncionesRecurso
process.spawnspawn*()id del proceso
process.spawn.monitoredspawn_monitored(), spawn_linked_monitored()id del proceso
process.spawn.linkedspawn_linked(), spawn_linked_monitored()id del proceso
process.hostspawn*(), exec()id del host
process.sendsend()PID destino
process.execexec()id del proceso
process.terminateterminate()PID destino
process.cancelcancel()PID destino
process.monitormonitor()PID destino
process.unmonitorunmonitor()PID destino
process.linklink()PID destino
process.unlinkunlink()PID destino
process.contextwith_context()”context”
process.security:with_actor(), :with_scope()”security”
process.registry.registerregistry.register()nombre
process.registry.unregisterregistry.unregister()nombre
process.registry.foreignregistry.register()PID destino

Los ámbitos de nombre de cluster están autorizados por variantes con sufijo de ámbito de estas acciones (process.registry.register.eventual, .consistent, .strong, y las acciones de unregister correspondientes), por lo que una política puede otorgar naming local separado del naming a nivel de cluster.

Algunas operaciones requieren múltiples permisos:

OperaciónPermisos requeridos
spawn()process.spawn + process.host
spawn_monitored()process.spawn + process.spawn.monitored + process.host
spawn_linked()process.spawn + process.spawn.linked + process.host
spawn_linked_monitored()process.spawn + process.spawn.monitored + process.spawn.linked + process.host
exec()process.exec + process.host
spawn con actor/ámbito personalizadopermisos de spawn + process.security
CondiciónTipo
No se encontró contextoerrors.INVALID
Contexto de frame no encontradoerrors.INVALID
Argumentos requeridos faltanteserrors.INVALID
Prefijo de tema reservado (@)errors.INVALID
Formato de duración inválidoerrors.INVALID
Nombre no registradoerrors.NOT_FOUND
Permiso denegadoerrors.PERMISSION_DENIED
Nombre ya registradoerrors.ALREADY_EXISTS

Consulte Manejo de Errores para trabajar con errores.