pgbus 0.17.1 → 0.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +48 -13
  4. data/app/controllers/concerns/pgbus/job_listing.rb +37 -0
  5. data/app/controllers/concerns/pgbus/process_listing.rb +17 -0
  6. data/app/controllers/pgbus/application_controller.rb +5 -2
  7. data/app/controllers/pgbus/batches_controller.rb +4 -1
  8. data/app/controllers/pgbus/dashboard_controller.rb +20 -6
  9. data/app/controllers/pgbus/dead_letter_controller.rb +27 -3
  10. data/app/controllers/pgbus/events_controller.rb +52 -3
  11. data/app/controllers/pgbus/insights_controller.rb +19 -1
  12. data/app/controllers/pgbus/jobs_controller.rb +45 -26
  13. data/app/controllers/pgbus/locks_controller.rb +7 -2
  14. data/app/controllers/pgbus/outbox_controller.rb +4 -1
  15. data/app/controllers/pgbus/processes_controller.rb +3 -1
  16. data/app/controllers/pgbus/queues_controller.rb +16 -4
  17. data/app/controllers/pgbus/recurring_tasks_controller.rb +5 -7
  18. data/app/frontend/pgbus/modules/charts.js +119 -77
  19. data/app/frontend/pgbus/style.css +1 -1
  20. data/app/frontend/pgbus/tailwind.css +18 -0
  21. data/app/helpers/pgbus/application_helper.rb +155 -113
  22. data/app/helpers/pgbus/button_helper.rb +88 -0
  23. data/app/helpers/pgbus/dashboard_helper.rb +157 -0
  24. data/app/helpers/pgbus/events_helper.rb +40 -0
  25. data/app/helpers/pgbus/insights_helper.rb +39 -0
  26. data/app/helpers/pgbus/processes_helper.rb +79 -0
  27. data/app/views/pgbus/batches/_batches_table.html.erb +16 -13
  28. data/app/views/pgbus/batches/show.html.erb +3 -4
  29. data/app/views/pgbus/dashboard/_processes_table.html.erb +11 -11
  30. data/app/views/pgbus/dashboard/_queue_health.html.erb +42 -51
  31. data/app/views/pgbus/dashboard/_queues_table.html.erb +18 -16
  32. data/app/views/pgbus/dashboard/_recent_failures.html.erb +16 -12
  33. data/app/views/pgbus/dashboard/_stats_cards.html.erb +70 -36
  34. data/app/views/pgbus/dashboard/show.html.erb +1 -1
  35. data/app/views/pgbus/dead_letter/_error.html.erb +13 -0
  36. data/app/views/pgbus/dead_letter/_messages_table.html.erb +37 -96
  37. data/app/views/pgbus/dead_letter/_row.html.erb +75 -0
  38. data/app/views/pgbus/dead_letter/index.html.erb +6 -9
  39. data/app/views/pgbus/dead_letter/show.html.erb +37 -21
  40. data/app/views/pgbus/events/_list.html.erb +55 -0
  41. data/app/views/pgbus/events/_processed_table.html.erb +45 -0
  42. data/app/views/pgbus/events/_replay.html.erb +10 -0
  43. data/app/views/pgbus/events/_row.html.erb +162 -0
  44. data/app/views/pgbus/events/_tabs.html.erb +13 -0
  45. data/app/views/pgbus/events/index.html.erb +27 -48
  46. data/app/views/pgbus/events/show.html.erb +25 -7
  47. data/app/views/pgbus/insights/_chart_card.html.erb +21 -0
  48. data/app/views/pgbus/insights/_latency_table.html.erb +20 -0
  49. data/app/views/pgbus/insights/_status_table.html.erb +19 -0
  50. data/app/views/pgbus/insights/_throughput_table.html.erb +18 -0
  51. data/app/views/pgbus/insights/show.html.erb +83 -100
  52. data/app/views/pgbus/jobs/_list.html.erb +64 -0
  53. data/app/views/pgbus/jobs/_row.html.erb +107 -0
  54. data/app/views/pgbus/jobs/_tabs.html.erb +14 -0
  55. data/app/views/pgbus/jobs/index.html.erb +10 -10
  56. data/app/views/pgbus/jobs/show.html.erb +18 -20
  57. data/app/views/pgbus/locks/_concurrency.html.erb +25 -23
  58. data/app/views/pgbus/locks/_uniqueness.html.erb +20 -22
  59. data/app/views/pgbus/outbox/index.html.erb +30 -27
  60. data/app/views/pgbus/processes/_processes_table.html.erb +6 -25
  61. data/app/views/pgbus/processes/_row.html.erb +48 -0
  62. data/app/views/pgbus/processes/_status.html.erb +4 -0
  63. data/app/views/pgbus/queues/_queues_list.html.erb +28 -32
  64. data/app/views/pgbus/queues/show.html.erb +69 -118
  65. data/app/views/pgbus/recurring_tasks/_tasks_table.html.erb +75 -76
  66. data/app/views/pgbus/recurring_tasks/index.html.erb +1 -1
  67. data/app/views/pgbus/recurring_tasks/show.html.erb +45 -51
  68. data/app/views/pgbus/shared/_empty_row.html.erb +2 -0
  69. data/app/views/pgbus/shared/_pager.html.erb +34 -0
  70. data/config/i18n-tasks.yml +11 -2
  71. data/config/locales/da.yml +405 -113
  72. data/config/locales/de.yml +405 -113
  73. data/config/locales/en.yml +405 -113
  74. data/config/locales/es.yml +404 -112
  75. data/config/locales/fi.yml +404 -112
  76. data/config/locales/fr.yml +406 -114
  77. data/config/locales/it.yml +405 -113
  78. data/config/locales/ja.yml +405 -113
  79. data/config/locales/nb.yml +405 -113
  80. data/config/locales/nl.yml +405 -113
  81. data/config/locales/pt.yml +406 -114
  82. data/config/locales/sv.yml +404 -112
  83. data/lib/generators/pgbus/templates/initializer.rb.erb +4 -0
  84. data/lib/pgbus/active_job/executor.rb +16 -6
  85. data/lib/pgbus/cli/dlq.rb +32 -5
  86. data/lib/pgbus/client.rb +4 -2
  87. data/lib/pgbus/configuration.rb +47 -2
  88. data/lib/pgbus/dead_letter_header.rb +129 -0
  89. data/lib/pgbus/doctor.rb +8 -4
  90. data/lib/pgbus/event_bus/handler.rb +18 -11
  91. data/lib/pgbus/event_bus/registry.rb +6 -0
  92. data/lib/pgbus/failed_event_recorder.rb +34 -0
  93. data/lib/pgbus/instrumentation.rb +2 -1
  94. data/lib/pgbus/mcp/base_tool.rb +25 -0
  95. data/lib/pgbus/mcp/tools/concurrency_tool.rb +23 -4
  96. data/lib/pgbus/mcp/tools/dlq_detail_tool.rb +4 -2
  97. data/lib/pgbus/mcp/tools/dlq_tool.rb +10 -4
  98. data/lib/pgbus/mcp/tools/locks_tool.rb +23 -5
  99. data/lib/pgbus/mcp/tools/recurring_tool.rb +33 -4
  100. data/lib/pgbus/outbox/poller.rb +1 -1
  101. data/lib/pgbus/process/consumer.rb +53 -3
  102. data/lib/pgbus/process/dispatcher.rb +1 -1
  103. data/lib/pgbus/process/supervisor.rb +32 -11
  104. data/lib/pgbus/process/worker.rb +45 -8
  105. data/lib/pgbus/recurring/scheduler.rb +2 -1
  106. data/lib/pgbus/version.rb +1 -1
  107. data/lib/pgbus/web/data_source/dashboard_signals.rb +170 -0
  108. data/lib/pgbus/web/data_source/dead_letter.rb +142 -0
  109. data/lib/pgbus/web/data_source/event_list.rb +161 -0
  110. data/lib/pgbus/web/data_source/job_list.rb +323 -0
  111. data/lib/pgbus/web/data_source/list_counts.rb +80 -0
  112. data/lib/pgbus/web/data_source/process_list.rb +69 -0
  113. data/lib/pgbus/web/data_source/queue_summary.rb +122 -0
  114. data/lib/pgbus/web/data_source.rb +132 -254
  115. data/lib/pgbus/web/dead_letter_reason.rb +81 -0
  116. data/lib/pgbus/web/event_state.rb +71 -0
  117. data/lib/pgbus/web/health_app.rb +7 -3
  118. data/lib/pgbus/web/health_verdict.rb +78 -0
  119. data/lib/pgbus/web/insights_charts.rb +84 -0
  120. data/lib/pgbus/web/job_state.rb +111 -0
  121. data/lib/pgbus/web/process_activity.rb +97 -0
  122. data/lib/pgbus/web/process_state.rb +187 -0
  123. data/lib/pgbus/web/queue_summary.rb +104 -0
  124. data/lib/pgbus/web/time_format.rb +128 -0
  125. metadata +43 -4
  126. data/app/views/pgbus/events/_pending_table.html.erb +0 -169
  127. data/app/views/pgbus/jobs/_enqueued_table.html.erb +0 -118
  128. data/app/views/pgbus/jobs/_failed_table.html.erb +0 -76
@@ -41,6 +41,7 @@ es:
41
41
  title: Procesos activos
42
42
  queue_health:
43
43
  dead_tuples: Tuplas muertas
44
+ empty: Aún no hay tablas de cola que medir
44
45
  headers:
45
46
  bloat: Bloat
46
47
  dead: Muertas
@@ -60,14 +61,34 @@ es:
60
61
  one: "%{count} tabla necesita vacuum"
61
62
  other: "%{count} tablas necesitan vacuum"
62
63
  title: Salud de Colas
64
+ words:
65
+ bloat:
66
+ critical: "%{ratio} en %{table} — las lecturas se ralentizan; ejecuta vacuum ahora (crítico por encima de %{critical}, avisa por encima de %{warn})"
67
+ none: Aún nada que medir
68
+ ok: "%{ratio} en %{table} — bien (avisa por encima de %{warn}, crítico por encima de %{critical})"
69
+ warn: "%{ratio} en %{table} — toca vacuum (avisa por encima de %{warn}, crítico por encima de %{critical})"
70
+ dead_tuples:
71
+ ok: Bien — avisa por encima de %{limit} filas muertas
72
+ warn: Por encima de %{limit} — autovacuum va retrasado; la tabla de abajo muestra dónde
73
+ transaction:
74
+ critical: Más de %{critical} — vacuum no puede recuperar filas hasta que termine; búscala en pg_stat_activity (avisa a los %{warn}; el veredicto de salud se degrada tras %{verdict})
75
+ none: Ninguna transacción abierta — vacuum puede recuperar todas las filas muertas (avisa a los %{warn}, alerta a los %{critical}; el veredicto de salud se degrada tras %{verdict})
76
+ ok: Bien — avisa a los %{warn}, alerta a los %{critical}; el veredicto de salud se degrada tras %{verdict}
77
+ warn: Más de %{warn} — una transacción larga impide que vacuum recupere filas (alerta a los %{critical}; el veredicto de salud se degrada tras %{verdict})
78
+ vacuum:
79
+ critical: Más de %{critical} — autovacuum no llega a estas tablas; revisa su configuración (avisa tras %{warn})
80
+ ok: Bien — avisa tras %{warn}, crítico tras %{critical}
81
+ unknown: Nunca se ha ejecutado vacuum, o las estadísticas no están disponibles
82
+ warn: Más de %{warn} — puede que autovacuum se esté retrasando (crítico tras %{critical})
63
83
  worst_bloat: Peor Bloat
64
84
  queues_table:
65
85
  empty: No se encontraron colas
66
86
  headers:
67
87
  depth: Profundidad
68
- oldest_claimable: Más antiguo disponible (s)
88
+ oldest_claimable: Más antiguo disponible
69
89
  parked: Aparcados
70
90
  queue: Cola
91
+ status: Estado
71
92
  total: Total
72
93
  visible: Visible
73
94
  title: Colas
@@ -75,7 +96,9 @@ es:
75
96
  recent_failures:
76
97
  empty: Sin fallos
77
98
  headers:
99
+ attempt: Intento
78
100
  error: Error
101
+ job: Job
79
102
  queue: Cola
80
103
  when: Cuándo
81
104
  title: Fallos recientes
@@ -83,19 +106,72 @@ es:
83
106
  show:
84
107
  title: Panel de control
85
108
  stats_cards:
109
+ dead_lettered: En mensajes muertos
110
+ dlq_newest_html: 'más reciente: %{error_class} en %{job} %{ago}'
111
+ dlq_newest_legacy_html: 'más reciente: %{job} %{ago} — sin motivo registrado'
112
+ dlq_newest_no_error_html: 'más reciente: %{job} %{ago} — sin error registrado'
113
+ dlq_none: Nada en mensajes muertos
114
+ dlq_see_why: abre la página de mensajes muertos para ver por qué murió cada uno
86
115
  enqueued: Encolado
87
- failed_dlq: Fallidos / DLQ
88
- failed_dlq_labels: Fallidos / Dead Lettered
116
+ enqueued_detail: "%{claimable} disponibles ahora · %{waiting} programados, en ejecución o reintentando"
117
+ enqueued_paused:
118
+ one: "%{count} en colas en pausa"
119
+ other: "%{count} en colas en pausa"
89
120
  parked_jobs: Trabajos aparcados
90
121
  parked_jobs_oldest: más antiguo %{age}
91
122
  processes: Procesos
123
+ processes_detail: "%{healthy} sanos · %{stalled} bloqueados · %{stale} obsoletos"
124
+ processes_none: No hay nada en ejecución — no se toma ningún trabajo
125
+ processes_stale: los procesos obsoletos dejaron de enviar latidos; sus trabajos en curso se ejecutan de nuevo cuando vence su visibility timeout
92
126
  queues: Colas
127
+ queues_detail: "%{paused} en pausa · %{dlq} mensajes muertos"
128
+ queues_undrained:
129
+ one: "%{count} tiene trabajos que nadie vacía"
130
+ other: "%{count} tienen trabajos que nadie vacía"
93
131
  recurring: Recurrente
132
+ recurring_detail: Tareas que el scheduler encola según su programación
133
+ retrying: Reintentando
134
+ retrying_due:
135
+ one: "%{count} vence ahora"
136
+ other: "%{count} vencen ahora"
137
+ retrying_newest: error más reciente %{error_class}
138
+ retrying_next_html: próximo intento %{time}
139
+ retrying_none: Nada se está reintentando
94
140
  throughput: Rendimiento
95
- throughput_unit: msgs/s
96
- view_tasks: Ver tareas
97
- visible: visible
141
+ throughput_detail: trabajos/min en los últimos %{minutes} min
142
+ throughput_unavailable: requiere estadísticas de trabajos (rails g pgbus:add_job_stats)
143
+ verdict:
144
+ links:
145
+ dlq: Mensajes muertos
146
+ processes: Procesos
147
+ look_at: 'Mira:'
148
+ meaning:
149
+ degraded: Algo requiere atención, pero los trabajos siguen fluyendo. /readyz sigue respondiendo listo.
150
+ ok: Toda cola con trabajo se está vaciando y todos los procesos envían latidos. /readyz responde listo.
151
+ stalled: Hay trabajos esperando y nadie los toma. /readyz responde no listo (503).
152
+ statuses:
153
+ degraded: DEGRADED
154
+ ok: OK
155
+ stalled: STALLED
156
+ title: 'Salud: %{status}'
157
+ unavailable: Veredicto de salud no disponible — no se pudieron leer las comprobaciones en que se basa; consulta el log
98
158
  dead_letter:
159
+ detail:
160
+ backtrace: Backtrace (primeras líneas)
161
+ died: 'Murió:'
162
+ dlq: 'Cola de mensajes muertos:'
163
+ error_from_attempt: Error del intento %{attempt}; los intentos %{from}–%{to} no registraron error.
164
+ source: 'Movido por:'
165
+ sources:
166
+ consumer: consumidor de eventos
167
+ worker: worker de jobs
168
+ why: Por qué murió
169
+ filters:
170
+ all: Todas
171
+ clear_error_class: Quitar filtro
172
+ error_class: 'Error: %{error_class}'
173
+ filter_error_class: Mostrar solo %{error_class}
174
+ label: Filtrar mensajes muertos
99
175
  index:
100
176
  discard_all: Descartar todo
101
177
  discard_all_confirm: "¿Descartar permanentemente todos los mensajes DLQ?"
@@ -115,10 +191,12 @@ es:
115
191
  empty: La cola de mensajes muertos está vacía
116
192
  full_json_payload: Carga JSON completa
117
193
  headers:
118
- enqueued: Encolado
194
+ actions: Acciones
195
+ attempts: Intentos
196
+ died: Murió
119
197
  id: ID
120
- job_class: Clase de trabajo
121
- reads: Lecturas
198
+ job: Job
199
+ reason: Motivo
122
200
  source_queue: Cola de origen
123
201
  headers_section: Encabezados
124
202
  job_id: 'ID de trabajo:'
@@ -131,6 +209,16 @@ es:
131
209
  visible_at: 'Visible en:'
132
210
  retry: Reintentar
133
211
  total_label: mensajes en la cola de mensajes fallidos
212
+ view: Ver
213
+ reasons:
214
+ error_earlier_attempt_html: 'Reintentos agotados. Último error registrado, del intento %{error_attempt}: %{error_class}: %{error_message}'
215
+ error_html: 'Reintentos agotados. Último error: %{error_class}: %{error_message}'
216
+ event_no_error_html: El handler falló en %{attempts} entregas (máx. %{max}) — no se registró ningún error del handler
217
+ no_error_recorded_html: Superó %{max} reintentos tras %{attempts} lecturas — no se registró ningún error; cada intento fallido se cayó antes de poder informar
218
+ not_recorded_html: Motivo no registrado (movido a la DLQ antes de pgbus %{version})
219
+ retried_before:
220
+ one: Reintentado desde la DLQ una vez antes.
221
+ other: Reintentado desde la DLQ %{count} veces antes.
134
222
  show:
135
223
  back: Volver a DLQ
136
224
  context: Contexto
@@ -138,8 +226,10 @@ es:
138
226
  discard_confirm: "¿Descartar permanentemente?"
139
227
  headers: Encabezados
140
228
  labels:
229
+ attempts: Intentos
230
+ died: Murió
231
+ dlq: Cola de mensajes muertos
141
232
  enqueued_at: Encolado en
142
- read_count: Conteo de lecturas
143
233
  source_queue: Cola de origen
144
234
  visibility_timeout: Tiempo de espera de visibilidad
145
235
  not_found: Mensaje no encontrado
@@ -163,6 +253,7 @@ es:
163
253
  mark_handled_failed: No se pudo marcar el evento como manejado.
164
254
  marked_handled: Evento marcado como manejado.
165
255
  none_selected: No hay eventos seleccionados.
256
+ payload_redacted: 'No guardado: el payload aún contiene valores ocultos ([FILTERED]) que reemplazarían los reales.'
166
257
  payload_update_failed: No se pudo actualizar la carga útil. Verifique que el JSON sea válido.
167
258
  payload_updated: Carga útil actualizada y evento reenviado a la cola.
168
259
  replay_failed: Evento no encontrado o no se pudo reproducir.
@@ -170,56 +261,118 @@ es:
170
261
  reroute_failed: No se pudo redirigir el evento.
171
262
  rerouted: Evento redirigido al manejador objetivo.
172
263
  index:
173
- discard_selected: Descartar seleccionados
174
- discard_selected_confirm: "¿Descartar eventos seleccionados?"
175
- pending_empty: No hay eventos pendientes
176
- pending_headers:
177
- enqueued: En cola
178
- handler_queue: Cola del manejador
179
- id: ID
180
- reads: Lecturas
181
- routing_key: Clave de enrutamiento
182
264
  pending_title: Eventos pendientes
183
- processed_empty: No se han procesado eventos aún
184
- processed_headers:
185
- event_id: ID del evento
186
- handler: Manejador
187
- processed_at: Procesado en
188
265
  processed_title: Eventos procesados
266
+ subscribers:
267
+ covered: Procesado por un consumer en ejecución
268
+ uncovered: Ningún consumer en ejecución cubre este patrón
269
+ unknown: Cobertura de consumers desconocida
270
+ view_pending: Ver pendientes
189
271
  subscribers_empty: No hay suscriptores registrados
190
272
  subscribers_headers:
273
+ consumer: Consumer
191
274
  handler: Manejador
192
275
  pattern: Patrón
276
+ pending: Pendientes
193
277
  queue: Cola
194
278
  subscribers_title: Suscriptores registrados
195
279
  title: Eventos
196
- pending_table:
197
- arguments: Carga útil
280
+ list:
198
281
  context: Contexto
199
282
  discard: Descartar
200
283
  discard_confirm: "¿Descartar este evento? Será archivado."
284
+ discard_failure_confirm: "¿Descartar este evento fallido? Su mensaje ya no está en la cola."
285
+ discard_selected: Descartar seleccionados
286
+ discard_selected_confirm: "¿Descartar eventos seleccionados?"
201
287
  edit_payload: Editar y reintentar
202
288
  edit_payload_confirm: "¿Actualizar la carga útil y reenviar este evento a la cola?"
203
289
  edit_payload_label: 'Carga útil JSON:'
290
+ empty:
291
+ all: No hay eventos pendientes
292
+ ready: No hay eventos esperando a ser procesados
293
+ retrying: No hay eventos esperando reintento
294
+ running: No hay eventos en proceso
295
+ scheduled: No hay eventos programados
204
296
  event_id: 'ID del evento:'
205
297
  full_json_payload: Carga útil JSON completa
298
+ headers:
299
+ actions: Acciones
300
+ attempts: Intentos
301
+ event: Evento
302
+ handler: Manejador
303
+ id: ID
304
+ reason: Próxima ejecución / Motivo
305
+ state: Estado
206
306
  headers_section: Encabezados
207
307
  mark_handled: Marcar como manejado
208
- mark_handled_confirm: "¿Marcar este evento como manejado? Será archivado y omitido en la reproducción."
308
+ mark_handled_confirm: "¿Marcar este evento como procesado? Su mensaje se archiva y el handler no lo ejecuta."
209
309
  metadata: Metadatos
210
310
  metadata_labels:
311
+ enqueued: 'Encolado:'
211
312
  last_read: 'Última lectura:'
313
+ published: 'Publicado:'
212
314
  read_count: 'Cantidad de lecturas:'
213
315
  visible_at: 'Visible en:'
316
+ payload: Carga útil
317
+ reasons:
318
+ handling_html: En proceso por %{handler} — reclamado %{ago} · el lease vence %{time}
319
+ lease_expired_html: Lease vencido (el consumer probablemente murió) — reentregando a %{handler}, intento %{attempt}
320
+ no_consumer_for_queue_html: Ningún consumer en ejecución se suscribe a %{pattern} (%{handler})
321
+ no_consumers_html: No hay ningún consumer sano en ejecución
322
+ orphaned_html: Falló con %{error} en %{handler} — el mensaje ya no está en la cola
323
+ paused_html: Cola en pausa
324
+ retrying_dlq_html: "%{handler} intento %{attempt}/%{max} falló: %{error} — la próxima lectura lo mueve a la DLQ"
325
+ retrying_due_html: "%{handler} intento %{attempt}/%{max} falló: %{error} — el próximo intento toca ahora"
326
+ retrying_html: "%{handler} intento %{attempt}/%{max} falló: %{error} — próximo intento %{time}"
327
+ scheduled_html: Programado — lo procesa %{handler} %{time}
328
+ waiting_html: 'Esperando — %{count} delante · siguiente: %{handler}'
329
+ waiting_unknown_html: Esperando a %{handler}
214
330
  reroute: Redirigir
215
331
  reroute_confirm: "¿Redirigir este evento a un manejador diferente?"
216
332
  reroute_label: 'Manejador objetivo:'
333
+ states:
334
+ ready: Listo
335
+ retrying: Reintentando
336
+ running: En proceso
337
+ scheduled: Programado
338
+ tabs:
339
+ all: Todos
340
+ ready: Listos
341
+ retrying: Reintentando
342
+ running: En proceso
343
+ scheduled: Programados
344
+ tabs_label: Estados de eventos
345
+ view_failure: Ver fallo
346
+ processed:
347
+ empty: No se han procesado eventos aún
348
+ headers:
349
+ actions: Acciones
350
+ event_id: ID del evento
351
+ handler: Manejador
352
+ reason: Motivo
353
+ state: Estado
354
+ reasons:
355
+ abandoned_html: El claim quedó en silencio %{ago} — la próxima entrega vuelve a ejecutar el handler
356
+ completed_html: Completado %{ago}
357
+ completed_legacy_html: Registrado %{ago} (claim de una fase; actualiza con pgbus:add_processed_event_completion)
358
+ handling_html: En proceso — claim renovado %{ago}
359
+ replay: Reproducir
360
+ replay_confirm: "¿Volver a entregar este evento a su handler con un nuevo ID de evento? El handler se ejecuta de nuevo."
361
+ replay_unavailable:
362
+ no_handler: El handler ya no está registrado
363
+ not_archived: Ya no está en el archivo
364
+ states:
365
+ abandoned: En silencio
366
+ completed: Completado
367
+ handling: En proceso
217
368
  show:
218
369
  back: Volver a eventos
219
370
  labels:
371
+ completed_at: Completado el
220
372
  event_id: ID del evento
221
373
  handler: Manejador
222
374
  processed_at: Procesado en
375
+ state: Estado
223
376
  not_found: Evento no encontrado
224
377
  title: Evento %{event_id}
225
378
  helpers:
@@ -231,6 +384,7 @@ es:
231
384
  bulk_select_row: Seleccionar %{id}
232
385
  bulk_selected: seleccionado
233
386
  pagination:
387
+ label: Paginación
234
388
  next: Siguiente
235
389
  previous: Anterior
236
390
  showing: Mostrando %{from}–%{to} de %{total}
@@ -245,24 +399,50 @@ es:
245
399
  healthy: Saludable
246
400
  stale: Obsoleto
247
401
  stalled: Bloqueado
402
+ time:
403
+ absolute_format: "%Y-%m-%d %H:%M:%S %Z"
404
+ clock_format: "%H:%M"
405
+ future: en %{distance}
406
+ now: ahora
407
+ past: hace %{distance}
408
+ range:
409
+ days:
410
+ one: "%{count} día"
411
+ other: "%{count} días"
412
+ hours:
413
+ one: "%{count} hora"
414
+ other: "%{count} horas"
415
+ minutes:
416
+ one: "%{count} minuto"
417
+ other: "%{count} minutos"
418
+ units:
419
+ days: "%{count}d"
420
+ hours: "%{count}h"
421
+ milliseconds: "%{count}ms"
422
+ minutes: "%{count}m"
423
+ seconds: "%{count}s"
248
424
  insights:
249
425
  show:
250
426
  charts:
251
- failed_to_load: Error al cargar datos del gráfico
252
- latency: Latencia de Cola (ms)
427
+ captions:
428
+ latency: Los trabajos esperaron %{avg} de media antes de que un worker los tomara, p95 %{p95}
429
+ status: "%{success} correctos, %{failed} fallidos, %{dead_lettered} en mensajes muertos"
430
+ throughput_html: "%{total} trabajos en los últimos %{range}, pico de %{peak} trabajos/min %{at}"
431
+ data_table: Tabla de datos
432
+ latency: Latencia de Cola
253
433
  latency_avg: Promedio
254
434
  latency_p95: P95
255
435
  no_data: Aún no hay datos
256
436
  series_name: Trabajos/min
257
437
  status_distribution: Distribución de estado
258
- throughput: Rendimiento (trabajos/min)
438
+ throughput: Rendimiento
259
439
  description_html: Métricas de desempeño laboral para los últimos %{range}
260
440
  latency_by_queue:
261
441
  empty: Aún no hay datos de latencia
262
442
  headers:
263
- avg: Promedio (ms)
443
+ avg: Promedio
264
444
  count: Cantidad
265
- p95: P95 (ms)
445
+ p95: P95
266
446
  queue: Cola
267
447
  title: Latencia por Cola
268
448
  live_streams:
@@ -282,6 +462,10 @@ es:
282
462
  job_class: Clase de trabajo
283
463
  max: Máximo
284
464
  title: Clases de Trabajo Más Lentas (duración promedio)
465
+ statuses:
466
+ dead_lettered: En mensajes muertos
467
+ failed: Fallidos
468
+ success: Correctos
285
469
  streams:
286
470
  summary:
287
471
  active: Activo
@@ -310,6 +494,20 @@ es:
310
494
  p99_latency: Latencia P99
311
495
  succeeded: Exitoso
312
496
  total_jobs: Total de Trabajos
497
+ tables:
498
+ captions:
499
+ latency_minute: Latencia de cola por minuto
500
+ latency_step: Latencia de cola por %{step}
501
+ status: Trabajos por estado final
502
+ throughput_minute: Trabajos por minuto
503
+ throughput_step: Trabajos por %{step}
504
+ headers:
505
+ avg: Promedio
506
+ from: Desde
507
+ highest_p95: p95 más alto
508
+ jobs: Trabajos
509
+ share: Proporción
510
+ status: Estado
313
511
  time_ranges:
314
512
  1h: 1h
315
513
  24h: 24h
@@ -317,60 +515,87 @@ es:
317
515
  7d: 7d
318
516
  title: Perspectivas
319
517
  jobs:
320
- enqueued_table:
518
+ index:
519
+ discard_all: Descartar Todo
520
+ discard_all_confirm: "¿Descartar todos los trabajos fallidos?"
521
+ discard_all_enqueued_notice: Se descartaron %{count} trabajos en cola y se liberaron sus bloqueos.
522
+ discard_selected: Descartar Seleccionados
523
+ discard_selected_confirm: "¿Descartar los elementos seleccionados?"
524
+ discarded_selected:
525
+ one: Se descartó 1 elemento seleccionado.
526
+ other: Se descartaron %{count} elementos seleccionados.
527
+ none_selected: No hay elementos seleccionados.
528
+ retry_all: Reintentar Todo
529
+ retry_all_confirm: "¿Reintentar todos los trabajos fallidos?"
530
+ title: Trabajos
531
+ list:
321
532
  arguments: Argumentos
322
533
  discard: Descartar
323
- discard_all: Descartar todos
324
- discard_all_confirm: "¿Descartar todos los trabajos en cola y liberar sus bloqueos? Esta acción no se puede deshacer."
325
- discard_confirm: "¿Descartar este mensaje?"
326
- empty: No hay trabajos en cola
534
+ discard_all_enqueued: Descartar todos los encolados
535
+ discard_all_enqueued_confirm: "¿Descartar todos los trabajos en cola y liberar sus bloqueos? Esta acción no se puede deshacer."
536
+ discard_confirm: "¿Descartar este trabajo?"
537
+ empty:
538
+ all: No hay trabajos
539
+ blocked: No hay trabajos bloqueados por un límite de concurrencia
540
+ ready: No hay trabajos esperando ejecución
541
+ retrying: No hay trabajos esperando reintento
542
+ running: No hay trabajos en ejecución
543
+ scheduled: No hay trabajos programados
327
544
  full_json_payload: Carga JSON completa
328
545
  headers:
329
- enqueued: En cola
546
+ actions: Acciones
547
+ attempts: Intentos
330
548
  id: ID
331
- job_class: Clase de Trabajo
549
+ job: Trabajo
332
550
  queue: Cola
333
- reads: Lecturas
551
+ reason: Próxima ejecución / Motivo
552
+ state: Estado
334
553
  headers_section: Encabezados
335
554
  job_id: 'ID del Trabajo:'
336
555
  metadata: Metadatos
337
556
  metadata_labels:
557
+ concurrency_key: 'Clave de concurrencia:'
558
+ enqueued: 'Encolado:'
338
559
  last_read: 'Última lectura:'
339
560
  locale: 'Configuración regional:'
340
561
  priority: 'Prioridad:'
341
- queue: 'Cola:'
342
562
  scheduled: 'Programado:'
343
563
  timezone: 'Zona horaria:'
344
564
  visible_at: 'Visible en:'
565
+ reasons:
566
+ blocked_html: Esperando un hueco de concurrencia en %{key} (ocupados %{held}/%{limit}) · aparcado %{ago}
567
+ blocked_no_slots_html: Esperando un hueco de concurrencia en %{key} · aparcado %{ago}
568
+ lease_expired_html: Concesión expirada (el worker probablemente murió) — reentregando, intento %{attempt}
569
+ no_workers_html: No hay ningún worker sano en ejecución
570
+ not_drained_html: Ningún worker procesa esta cola
571
+ orphaned_html: Falló con %{error} — el mensaje ya no está en la cola
572
+ paused_html: Cola en pausa
573
+ retrying_dlq_html: 'El intento %{attempt}/%{max} falló: %{error} — la próxima lectura lo mueve a la DLQ'
574
+ retrying_due_html: 'El intento %{attempt}/%{max} falló: %{error} — el próximo intento es ahora'
575
+ retrying_html: 'El intento %{attempt}/%{max} falló: %{error} — próximo intento %{time}'
576
+ running_html: Reclamado %{ago} · la concesión expira %{time}
577
+ scheduled_html: Programado — se ejecuta %{time}
578
+ waiting_html: Esperando — %{count} por delante
579
+ waiting_priority_html: Esperando — %{count} por delante con esta prioridad
580
+ waiting_unknown_html: Esperando a ser recogido
345
581
  retry: Reintentar
346
582
  retry_confirm: "¿Restablecer tiempo de visibilidad y reintentar?"
347
- title: Trabajos en Cola
348
- failed_table:
349
- discard: Descartar
350
- discard_confirm: "¿Descartar este trabajo?"
351
- empty: No hay trabajos fallidos
352
- headers:
353
- actions: Acciones
354
- error: Error
355
- failed: Fallado
356
- id: ID
357
- queue: Cola
358
- retries: Reintentos
359
- retry: Reintentar
360
- title: Trabajos Fallidos
361
- index:
362
- discard_all: Descartar Todo
363
- discard_all_confirm: "¿Descartar todos los trabajos fallidos?"
364
- discard_all_enqueued_notice: Se descartaron %{count} trabajos en cola y se liberaron sus bloqueos.
365
- discard_selected: Descartar Seleccionados
366
- discard_selected_confirm: "¿Descartar los elementos seleccionados?"
367
- discarded_selected:
368
- one: Se descartó 1 elemento seleccionado.
369
- other: Se descartaron %{count} elementos seleccionados.
370
- none_selected: No hay elementos seleccionados.
371
- retry_all: Reintentar Todo
372
- retry_all_confirm: "¿Reintentar todos los trabajos fallidos?"
373
- title: Trabajos
583
+ states:
584
+ blocked: Bloqueado
585
+ ready: Listo
586
+ retrying: Reintentando
587
+ running: En ejecución
588
+ scheduled: Programado
589
+ tabs:
590
+ all: Todos
591
+ blocked: Bloqueados
592
+ ready: Listos
593
+ retrying: Reintentando
594
+ running: En ejecución
595
+ scheduled: Programados
596
+ tabs_label: Estados de trabajos
597
+ view_failure: Ver fallo
598
+ view_locks: Ver bloqueos
374
599
  show:
375
600
  back: Volver a Trabajos
376
601
  backtrace: Rastreo de pila
@@ -423,6 +648,7 @@ es:
423
648
  other: "¿Descartar los %{count} trabajos aparcados detrás de esta clave? Nunca se ejecutarán."
424
649
  empty: No hay claves de concurrencia en uso
425
650
  headers:
651
+ actions: Acciones
426
652
  in_use: En uso
427
653
  key: Clave
428
654
  lease: Concesión
@@ -456,6 +682,7 @@ es:
456
682
  discard_selected_confirm: "¿Descartar los bloqueos seleccionados?"
457
683
  empty: No hay bloqueos activos
458
684
  headers:
685
+ actions: Acciones
459
686
  age: Antigüedad
460
687
  lock_key: Clave de bloqueo
461
688
  msg_id: ID de mensaje
@@ -483,8 +710,6 @@ es:
483
710
  pending: Pendiente
484
711
  published: Publicado
485
712
  stats:
486
- no_age: "—"
487
- oldest_age: "%{seconds}s"
488
713
  oldest_unpublished: Más antiguo no publicado
489
714
  total: Total
490
715
  unpublished: No publicado
@@ -493,18 +718,76 @@ es:
493
718
  index:
494
719
  title: Procesos
495
720
  processes_table:
721
+ capsule: cápsula %{capsule} · proceso %{process}
496
722
  empty: No hay procesos en ejecución
497
723
  headers:
498
- hostname: Nombre del host
499
- kind: Tipo
500
- last_heartbeat: Último latido
501
- metadata: Metadatos
502
- pid: PID
724
+ activity: Actividad
725
+ heartbeat: Latido
726
+ process: Proceso
727
+ recycle: Reciclaje
503
728
  status: Estado
504
- rates:
505
- dequeued: extraídos
506
- failed: fallidos
507
- processed: procesados
729
+ no_raw_metadata: Sin otros metadatos
730
+ raw_metadata: Otros metadatos
731
+ started: Iniciado
732
+ under_supervisor: bajo el supervisor %{pid}
733
+ uptime: activo %{duration}
734
+ state:
735
+ activity:
736
+ buffered: "%{number} en búfer"
737
+ busy_slots: "%{busy}/%{capacity} slots ocupados"
738
+ busy_threads: "%{busy}/%{capacity} hilos ocupados"
739
+ consumes: Consume %{topics}
740
+ drains: Vacía %{queues}
741
+ drains_all: Vacía todas las colas
742
+ failed_rate: "%{rate} fallidos/s"
743
+ handled: "%{number} gestionados"
744
+ maintenance: Ejecuta mantenimiento cada %{interval} (trabajos programados, procesos caídos, archivos)
745
+ outbox: Publica entradas del outbox
746
+ rate: "%{rate} trabajos/s"
747
+ schedule:
748
+ one: Ejecuta %{count} tarea recurrente, revisa cada %{interval}
749
+ other: Ejecuta %{count} tareas recurrentes, revisa cada %{interval}
750
+ slots:
751
+ one: "%{count} slot"
752
+ other: "%{count} slots"
753
+ supervises: Supervisa %{children}
754
+ supervises_none: No supervisa procesos en este host
755
+ threads:
756
+ one: "%{count} hilo"
757
+ other: "%{count} hilos"
758
+ kinds:
759
+ consumer:
760
+ one: "%{count} consumidor"
761
+ other: "%{count} consumidores"
762
+ dispatcher:
763
+ one: dispatcher
764
+ other: "%{count} dispatchers"
765
+ outbox_poller:
766
+ one: poller del outbox
767
+ other: "%{count} pollers del outbox"
768
+ scheduler:
769
+ one: scheduler
770
+ other: "%{count} schedulers"
771
+ worker:
772
+ one: "%{count} worker"
773
+ other: "%{count} workers"
774
+ next:
775
+ stale_reaped: probablemente muerto; se elimina en la próxima pasada del dispatcher (en menos de %{within})
776
+ stale_unreaped: probablemente muerto; no hay un dispatcher vivo que lo elimine
777
+ stalled_maintenance: los trabajos programados, la limpieza de procesos caídos y la compactación de archivos no avanzan
778
+ stalled_schedule: las tareas recurrentes no se están encolando
779
+ stalled_standalone: no hay supervisor que lo reinicie
780
+ stalled_supervised: el watchdog del supervisor lo reinicia
781
+ reasons:
782
+ healthy_detection_off_html: Latido %{ago} (límite %{limit}) · detección de bloqueos desactivada
783
+ healthy_heartbeat_html: Latido %{ago} (límite %{limit})
784
+ healthy_loop_html: El bucle avanzó %{ago} (límite %{limit})
785
+ stale_html: Sin latido desde hace %{age} (límite %{limit})
786
+ stalled_html: El bucle avanzó por última vez %{ago} (límite %{limit})
787
+ recycle:
788
+ jobs: "%{done} / %{limit} trabajos"
789
+ lifetime: activo %{uptime} / %{limit}
790
+ memory: "%{used} / %{limit} MB"
508
791
  queues:
509
792
  destroy:
510
793
  success: Cola %{name} eliminada.
@@ -517,59 +800,70 @@ es:
517
800
  headers:
518
801
  actions: Acciones
519
802
  depth: Profundidad
520
- newest: Más nuevo (s)
521
- oldest_claimable: Más antiguo disponible (s)
803
+ newest: Más nuevo
804
+ oldest_claimable: Más antiguo disponible
522
805
  parked: Aparcados
523
806
  queue: Cola
524
807
  total_ever: Total acumulado
525
808
  visible: Visible
526
809
  pause: Pausar
527
810
  pause_confirm: "¿Pausar el procesamiento de %{name}?"
528
- paused: Pausado
529
811
  purge: Purgar
530
812
  purge_confirm: "¿Purgar todos los mensajes de %{name}?"
531
813
  resume: Reanudar
532
814
  show:
533
- arguments: Argumentos
534
815
  back: Volver a colas
535
816
  delete_confirm: "¿Eliminar permanentemente esta cola? Esto no se puede deshacer."
536
817
  delete_queue: Eliminar cola
537
- depth: 'Profundidad:'
538
- discard: Descartar
539
- discard_confirm: "¿Descartar este mensaje?"
540
- empty: La cola está vacía
541
- full_json_payload: Carga JSON completa
542
- headers:
543
- enqueued: Encolado
544
- id: ID
545
- job_class: Clase de Trabajo
546
- reads: Lecturas
547
- vt: VT
548
- headers_section: Encabezados
549
- job_id: 'ID del Trabajo:'
818
+ dlq_link: Reintentarlos o descartarlos en la página de Dead Letter
819
+ dlq_pointer:
820
+ one: Cola de mensajes muertos de %{logical} — %{count} mensaje.
821
+ other: Cola de mensajes muertos de %{logical} — %{count} mensajes.
550
822
  message_discard_failed: No se pudo descartar el mensaje.
551
823
  message_discarded: Mensaje descartado.
552
824
  message_retried: Visibilidad del mensaje restablecida.
553
825
  message_retry_failed: No se pudo reintentar el mensaje.
554
- metadata: Metadatos
555
- metadata_labels:
556
- last_read: 'Última lectura:'
557
- locale: 'Configuración regional:'
558
- priority: 'Prioridad:'
559
- queue: 'Cola:'
560
- scheduled: 'Programado:'
561
- timezone: 'Zona horaria:'
562
- visible_at: 'Visible en:'
563
- oldest: 'Más antiguo:'
564
- oldest_claimable: 'Más antiguo disponible:'
565
- parked: 'Aparcados:'
826
+ metrics:
827
+ claimable: Disponibles ahora
828
+ depth: Profundidad
829
+ oldest: Más antiguo
830
+ oldest_claimable: Más antiguo disponible
831
+ parked: Aparcados
832
+ total: Total histórico
833
+ other_levels: 'Otros niveles de prioridad:'
566
834
  pause: Pausar
567
835
  pause_confirm: "¿Pausar el procesamiento?"
568
836
  purge_confirm: "¿Purgar todos los mensajes?"
569
837
  purge_queue: Purgar cola
570
838
  resume: Reanudar
571
- retry: Reintentar
572
- retry_confirm: "¿Restablecer tiempo de visibilidad y reintentar?"
839
+ summary:
840
+ backlog_html: "%{visible} disponibles ahora, el más antiguo lleva %{age} esperando · %{parked} aparcados (programados o en reintento)"
841
+ backlog_parked_only_html: Nada disponible ahora · %{parked} aparcados (programados o en reintento)
842
+ dlq_html: 'Cola de mensajes muertos de %{logical}: los trabajos llegan aquí tras %{max} intentos fallidos'
843
+ drained_by_html:
844
+ one: La vacía %{capsules} (%{count} worker sano)
845
+ other: La vacía %{capsules} (%{count} workers sanos)
846
+ drained_live_html:
847
+ one: La vacía %{count} worker sano que escucha esta cola
848
+ other: La vacían %{count} workers sanos que escuchan esta cola
849
+ drained_wildcard_html:
850
+ one: La vacía una cápsula de workers comodín (%{count} worker sano)
851
+ other: La vacía una cápsula de workers comodín (%{count} workers sanos)
852
+ empty_html: Nada en espera
853
+ handler_html: Cola de manejador de eventos — la vacían los consumidores (%{count} sanos)
854
+ no_consumers_html:
855
+ one: Cola de manejador de eventos sin consumidor sano — %{count} evento espera
856
+ other: Cola de manejador de eventos sin consumidor sano — %{count} eventos esperan
857
+ no_workers_html:
858
+ one: Ningún worker sano en ejecución — %{count} trabajo está disponible pero nadie lo toma
859
+ other: Ningún worker sano en ejecución — %{count} trabajos están disponibles pero nadie los toma
860
+ not_drained_html: Ninguna cápsula de workers vacía esta cola — los trabajos esperan hasta que se configure una
861
+ paused_circuit_breaker_html: 'Pausada automáticamente %{ago} tras %{failures} fallos consecutivos — se reanuda %{time} (disparo #%{trip})'
862
+ paused_operator_html: Pausada %{ago} — %{reason}
863
+ paused_operator_no_reason_html: Pausada %{ago} por un operador
864
+ priority_level_html: Nivel de prioridad %{level} de %{logical}
865
+ stream_html: Cola de stream — se entrega con peek, los workers no la vacían
866
+ summary_label: Resumen de la cola
573
867
  table_health:
574
868
  headers:
575
869
  bloat: Bloat
@@ -579,8 +873,6 @@ es:
579
873
  table: Tabla
580
874
  oldest_txn: 'Transacción abierta más antigua:'
581
875
  title: Salud de Tablas
582
- total: 'Total:'
583
- visible: 'Visible:'
584
876
  recurring_tasks:
585
877
  index:
586
878
  task_count: