Grupos de Proceso
Los grupos de proceso permiten que los procesos se unan a grupos con nombre y reciban difusiones dirigidas a un grupo, con la membresía rastreada en todos los nodos del cluster. El modelo sigue pg de Erlang/OTP: los grupos se crean al primer join, un proceso puede pertenecer a muchos grupos (y unirse a un grupo varias veces), y no hay registro central — cada nodo mantiene el estado y se reconcilia con los peers a través de gossip.
La API Lua está documentada en Grupos de Proceso; esta página cubre el tipo de entrada de ámbito y su configuración. Ver la Guía de Cluster para el modelo de membresía circundante.
Tipo de Entrada
| Tipo | Descripción |
|---|---|
pg.scope |
Un espacio de nombres de grupos de proceso independiente con su propio estado de membresía y malla de cluster |
Cada ámbito está aislado: los grupos y miembros en un ámbito son invisibles para otro. Un proceso abre un ámbito por su ID de entrada (pg.open("app:pg")) y opera dentro de él.
- name: pg
kind: pg.scope
lifecycle:
auto_start: true
Configuración
Todos los campos son opcionales y tienen valores por defecto ajustados para un cluster típico.
| Campo | Tipo | Por defecto | Descripción |
|---|---|---|---|
protocol_timeout |
duration | 5s | Tiempo de espera para operaciones de sincronización/descubrimiento entre nodos |
broadcast_timeout |
duration | 5s | Tiempo de espera para entregar una difusión a un solo miembro |
anti_entropy_interval |
duration | 30s | Cadencia del bucle de reconciliación; se sincroniza un peer por tick (0 deshabilita) |
circuit_breaker_failures |
int | 3 | Fallos de envío consecutivos a un nodo antes de que su circuito se abra |
circuit_breaker_reset_time |
duration | 10s | Espera antes de que un circuito abierto pase a semi-abierto para un envío de prueba |
max_retries |
int | 3 | Intentos de reintento para una difusión fallida (0 deshabilita los reintentos) |
retry_base_delay |
duration | 100ms | Retraso de backoff inicial entre reintentos |
retry_max_delay |
duration | 1s | Retraso de backoff máximo |
action_queue_size |
int | 256 | Profundidad en la que se registra una advertencia de "aproximándose a la capacidad" |
action_queue_max_size |
int | 1024 | Capacidad máxima de la cola del bucle de eventos interno; las operaciones se descartan cuando está llena |
monitor_buffer |
int | 64 | Capacidad del canal de eventos por suscripción; los eventos se descartan para un suscriptor cuyo buffer se llena |
max_groups |
int | 0 | Máximo de grupos distintos (0 = ilimitado) |
max_members_per_group |
int | 0 | Máximo de miembros por grupo, contando multi-joins (0 = ilimitado) |
- name: pg
kind: pg.scope
anti_entropy_interval: 30s
circuit_breaker_failures: 3
max_members_per_group: 10000
lifecycle:
auto_start: true
Cómo Funciona
Estado de escritor único. Cada ámbito ejecuta un bucle de eventos de una sola goroutine (el patrón gen_server). Todas las mutaciones se serializan a través de él; las lecturas de miembros y grupos se sirven desde instantáneas publicadas atómicamente, por lo que nunca bloquean el bucle.
Propagación de join/leave. Un join o leave local se aplica al bucle y luego se distribuye en abanico hacia la unión de los peers de membresía activos y cualquier nodo remoto descubierto previamente. Enviar a esa unión — en lugar de solo a los peers descubiertos por gossip — asegura que un nodo recién unido o aún no convergido reciba el cambio.
Difusión. broadcast toma una instantánea de la lista completa de miembros del cluster dentro del bucle, luego entrega a cada miembro fuera del bucle para que un receptor lento no pueda detener el ámbito. broadcast_local hace lo mismo pero solo para miembros en el nodo local.
Monitor y eventos. Suscribirse y tomar instantánea de los miembros actuales ocurren en un tick del bucle de eventos, por lo que un suscriptor nunca pierde ni cuenta doble un cambio que compite con la suscripción. Los suscriptores reciben eventos member.joined / member.left; un leave para un proceso que se unió N veces reporta el PID N veces, preservando la multiplicidad.
Anti-entropía y descubrimiento. Al arrancar, un ámbito envía mensajes de descubrimiento a un pequeño subconjunto aleatorio de peers (limitado para evitar una tormenta N² cuando muchos nodos se reinician a la vez). Cuando un nodo se une, recibe una sincronización de estado completo. El bucle de anti-entropía luego periódicamente empuja una sincronización completa a un peer a la vez, de modo que cualquier difusión que un peer haya perdido eventualmente converge. El receptor aplica una sincronización diferencial — solo los miembros realmente añadidos o eliminados emiten eventos.
Circuit breakers. Un circuit breaker por nodo rastrea los fallos de envío consecutivos. Tras circuit_breaker_failures fallos se abre y los envíos a ese nodo se omiten hasta que transcurre circuit_breaker_reset_time, cuando se permite un envío de prueba. Las difusiones de join/leave que encuentran un breaker abierto se reintentan con backoff exponencial hasta max_retries.
Observabilidad
Una verificación de liveness (pg.broadcast_recent.<scope>) reporta unhealthy si un ámbito no ve tráfico de difusión durante un período prolongado, detectando un bucle de eventos bloqueado o una partición persistente. Ver la Guía de Observabilidad.
Ver También
- Grupos de Proceso - La API Lua
- Cluster - Membresía y el modelo de clustering
- Modelo de Procesos - Procesos, PIDs y mensajería