pgbus 0.14.1 → 0.15.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +33 -0
- data/Rakefile +6 -1
- data/app/helpers/pgbus/application_helper.rb +7 -0
- data/app/models/pgbus/batch_entry.rb +78 -6
- data/app/models/pgbus/batch_execution.rb +28 -0
- data/app/models/pgbus/blocked_execution.rb +2 -2
- data/app/models/pgbus/uniqueness_key.rb +50 -4
- data/app/views/pgbus/batches/_batches_table.html.erb +3 -3
- data/app/views/pgbus/batches/show.html.erb +7 -7
- data/app/views/pgbus/dead_letter/show.html.erb +17 -0
- data/app/views/pgbus/events/_pending_table.html.erb +21 -0
- data/app/views/pgbus/jobs/show.html.erb +17 -0
- data/config/locales/da.yml +5 -2
- data/config/locales/de.yml +5 -2
- data/config/locales/en.yml +5 -2
- data/config/locales/es.yml +5 -2
- data/config/locales/fi.yml +5 -2
- data/config/locales/fr.yml +5 -2
- data/config/locales/it.yml +5 -2
- data/config/locales/ja.yml +5 -2
- data/config/locales/nb.yml +5 -2
- data/config/locales/nl.yml +5 -2
- data/config/locales/pt.yml +5 -2
- data/config/locales/sv.yml +5 -2
- data/lib/generators/pgbus/add_batch_callback_jobs_generator.rb +47 -0
- data/lib/generators/pgbus/add_batch_executions_generator.rb +44 -0
- data/lib/generators/pgbus/templates/add_batch_callback_jobs.rb.erb +13 -0
- data/lib/generators/pgbus/templates/add_batch_executions.rb.erb +50 -0
- data/lib/generators/pgbus/templates/initializer.rb.erb +2 -0
- data/lib/generators/pgbus/templates/migration.rb.erb +23 -2
- data/lib/pgbus/active_job/adapter.rb +146 -28
- data/lib/pgbus/active_job/batch_id.rb +48 -0
- data/lib/pgbus/active_job/current_attributes.rb +52 -0
- data/lib/pgbus/active_job/executor.rb +45 -9
- data/lib/pgbus/batch/sweep.rb +163 -0
- data/lib/pgbus/batch.rb +448 -63
- data/lib/pgbus/client/fair_read.rb +187 -0
- data/lib/pgbus/client.rb +221 -18
- data/lib/pgbus/concurrency/blocked_execution.rb +14 -1
- data/lib/pgbus/configuration.rb +81 -1
- data/lib/pgbus/current_attributes.rb +156 -0
- data/lib/pgbus/engine.rb +2 -0
- data/lib/pgbus/event.rb +7 -2
- data/lib/pgbus/event_bus/handler.rb +12 -2
- data/lib/pgbus/event_bus/publisher.rb +37 -2
- data/lib/pgbus/event_bus/subscriber.rb +4 -0
- data/lib/pgbus/fair_share.rb +110 -0
- data/lib/pgbus/generators/migration_detector.rb +30 -0
- data/lib/pgbus/instrumentation.rb +5 -0
- data/lib/pgbus/outbox/poller.rb +6 -7
- data/lib/pgbus/outbox.rb +8 -1
- data/lib/pgbus/process/consumer.rb +38 -1
- data/lib/pgbus/process/dispatcher.rb +41 -17
- data/lib/pgbus/process/worker.rb +41 -0
- data/lib/pgbus/recurring/schedule.rb +12 -1
- data/lib/pgbus/testing.rb +2 -1
- data/lib/pgbus/uniqueness.rb +35 -7
- data/lib/pgbus/version.rb +1 -1
- data/lib/pgbus/web/data_source.rb +47 -9
- data/lib/pgbus/web/job_context.rb +80 -0
- data/lib/pgbus.rb +2 -0
- metadata +13 -1
data/config/locales/en.yml
CHANGED
|
@@ -19,10 +19,10 @@ en:
|
|
|
19
19
|
completed: Completed
|
|
20
20
|
created_at: Created At
|
|
21
21
|
details: Details
|
|
22
|
-
|
|
22
|
+
failed: Failed
|
|
23
23
|
finished_at: Finished At
|
|
24
24
|
not_found: Batch not found
|
|
25
|
-
|
|
25
|
+
on_failure: On Failure
|
|
26
26
|
on_finish: On Finish
|
|
27
27
|
on_success: On Success
|
|
28
28
|
progress: Progress
|
|
@@ -131,6 +131,7 @@ en:
|
|
|
131
131
|
total_label: messages in dead letter queue
|
|
132
132
|
show:
|
|
133
133
|
back: Back to DLQ
|
|
134
|
+
context: Context
|
|
134
135
|
discard: Discard
|
|
135
136
|
discard_confirm: Permanently discard?
|
|
136
137
|
headers: Headers
|
|
@@ -194,6 +195,7 @@ en:
|
|
|
194
195
|
title: Events
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Payload
|
|
198
|
+
context: Context
|
|
197
199
|
discard: Discard
|
|
198
200
|
discard_confirm: Discard this event? It will be archived.
|
|
199
201
|
edit_payload: Edit & Retry
|
|
@@ -372,6 +374,7 @@ en:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Back to Jobs
|
|
374
376
|
backtrace: Backtrace
|
|
377
|
+
context: Context
|
|
375
378
|
discard: Discard
|
|
376
379
|
discard_confirm: Discard this job permanently?
|
|
377
380
|
error_message: Error Message
|
data/config/locales/es.yml
CHANGED
|
@@ -19,10 +19,10 @@ es:
|
|
|
19
19
|
completed: Completados
|
|
20
20
|
created_at: Creado el
|
|
21
21
|
details: Detalles
|
|
22
|
-
|
|
22
|
+
failed: Fallados
|
|
23
23
|
finished_at: Finalizado el
|
|
24
24
|
not_found: Lote no encontrado
|
|
25
|
-
|
|
25
|
+
on_failure: Al fallar
|
|
26
26
|
on_finish: Al finalizar
|
|
27
27
|
on_success: Al tener éxito
|
|
28
28
|
progress: Progreso
|
|
@@ -131,6 +131,7 @@ es:
|
|
|
131
131
|
total_label: mensajes en la cola de mensajes fallidos
|
|
132
132
|
show:
|
|
133
133
|
back: Volver a DLQ
|
|
134
|
+
context: Contexto
|
|
134
135
|
discard: Descartar
|
|
135
136
|
discard_confirm: "¿Descartar permanentemente?"
|
|
136
137
|
headers: Encabezados
|
|
@@ -194,6 +195,7 @@ es:
|
|
|
194
195
|
title: Eventos
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Carga útil
|
|
198
|
+
context: Contexto
|
|
197
199
|
discard: Descartar
|
|
198
200
|
discard_confirm: "¿Descartar este evento? Será archivado."
|
|
199
201
|
edit_payload: Editar y reintentar
|
|
@@ -372,6 +374,7 @@ es:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Volver a Trabajos
|
|
374
376
|
backtrace: Rastreo de pila
|
|
377
|
+
context: Contexto
|
|
375
378
|
discard: Descartar
|
|
376
379
|
discard_confirm: "¿Descartar este trabajo permanentemente?"
|
|
377
380
|
error_message: Mensaje de error
|
data/config/locales/fi.yml
CHANGED
|
@@ -19,10 +19,10 @@ fi:
|
|
|
19
19
|
completed: Valmiit
|
|
20
20
|
created_at: Luotu
|
|
21
21
|
details: Tiedot
|
|
22
|
-
|
|
22
|
+
failed: Epäonnistuneet
|
|
23
23
|
finished_at: Valmistunut
|
|
24
24
|
not_found: Erää ei löytynyt
|
|
25
|
-
|
|
25
|
+
on_failure: Epäonnistumisessa
|
|
26
26
|
on_finish: Valmistumisessa
|
|
27
27
|
on_success: Onnistumisessa
|
|
28
28
|
progress: Edistyminen
|
|
@@ -131,6 +131,7 @@ fi:
|
|
|
131
131
|
total_label: viestiä dead letter -jonossa
|
|
132
132
|
show:
|
|
133
133
|
back: Takaisin DLQ:hon
|
|
134
|
+
context: Konteksti
|
|
134
135
|
discard: Hylkää
|
|
135
136
|
discard_confirm: Hylätään pysyvästi?
|
|
136
137
|
headers: Otsikot
|
|
@@ -194,6 +195,7 @@ fi:
|
|
|
194
195
|
title: Tapahtumat
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Kuorma
|
|
198
|
+
context: Konteksti
|
|
197
199
|
discard: Hylkää
|
|
198
200
|
discard_confirm: Hylätäänkö tämä tapahtuma? Se arkistoidaan.
|
|
199
201
|
edit_payload: Muokkaa ja yritä uudelleen
|
|
@@ -372,6 +374,7 @@ fi:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Takaisin töihin
|
|
374
376
|
backtrace: Takautumisketju
|
|
377
|
+
context: Konteksti
|
|
375
378
|
discard: Hylkää
|
|
376
379
|
discard_confirm: Hylkää tämä työ pysyvästi?
|
|
377
380
|
error_message: Virheilmoitus
|
data/config/locales/fr.yml
CHANGED
|
@@ -19,10 +19,10 @@ fr:
|
|
|
19
19
|
completed: Terminées
|
|
20
20
|
created_at: Créé le
|
|
21
21
|
details: Détails
|
|
22
|
-
|
|
22
|
+
failed: Échouées
|
|
23
23
|
finished_at: Terminé le
|
|
24
24
|
not_found: Lot non trouvé
|
|
25
|
-
|
|
25
|
+
on_failure: En cas d'échec
|
|
26
26
|
on_finish: À la fin
|
|
27
27
|
on_success: Au succès
|
|
28
28
|
progress: Progression
|
|
@@ -131,6 +131,7 @@ fr:
|
|
|
131
131
|
total_label: messages dans la file de lettres mortes
|
|
132
132
|
show:
|
|
133
133
|
back: Retour à la DLQ
|
|
134
|
+
context: Contexte
|
|
134
135
|
discard: Ignorer
|
|
135
136
|
discard_confirm: Ignorer définitivement ?
|
|
136
137
|
headers: En-têtes
|
|
@@ -194,6 +195,7 @@ fr:
|
|
|
194
195
|
title: Événements
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Charge utile
|
|
198
|
+
context: Contexte
|
|
197
199
|
discard: Jeter
|
|
198
200
|
discard_confirm: Jeter cet événement ? Il sera archivé.
|
|
199
201
|
edit_payload: Modifier & Réessayer
|
|
@@ -372,6 +374,7 @@ fr:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Retour aux travaux
|
|
374
376
|
backtrace: Trace de la pile
|
|
377
|
+
context: Contexte
|
|
375
378
|
discard: Ignorer
|
|
376
379
|
discard_confirm: Supprimer ce travail définitivement ?
|
|
377
380
|
error_message: Message d'erreur
|
data/config/locales/it.yml
CHANGED
|
@@ -19,10 +19,10 @@ it:
|
|
|
19
19
|
completed: Completati
|
|
20
20
|
created_at: Creato il
|
|
21
21
|
details: Dettagli
|
|
22
|
-
|
|
22
|
+
failed: Falliti
|
|
23
23
|
finished_at: Terminato il
|
|
24
24
|
not_found: Lotto non trovato
|
|
25
|
-
|
|
25
|
+
on_failure: Al fallimento
|
|
26
26
|
on_finish: Al termine
|
|
27
27
|
on_success: Al successo
|
|
28
28
|
progress: Progresso
|
|
@@ -131,6 +131,7 @@ it:
|
|
|
131
131
|
total_label: messaggi nella coda dei messaggi non recapitati
|
|
132
132
|
show:
|
|
133
133
|
back: Torna a DLQ
|
|
134
|
+
context: Contesto
|
|
134
135
|
discard: Scarta
|
|
135
136
|
discard_confirm: Scartare definitivamente?
|
|
136
137
|
headers: Intestazioni
|
|
@@ -194,6 +195,7 @@ it:
|
|
|
194
195
|
title: Eventi
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Payload
|
|
198
|
+
context: Contesto
|
|
197
199
|
discard: Scarta
|
|
198
200
|
discard_confirm: Scartare questo evento? Verrà archiviato.
|
|
199
201
|
edit_payload: Modifica e riprova
|
|
@@ -372,6 +374,7 @@ it:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Torna ai Lavori
|
|
374
376
|
backtrace: Traccia dello stack
|
|
377
|
+
context: Contesto
|
|
375
378
|
discard: Scarta
|
|
376
379
|
discard_confirm: Scartare definitivamente questo lavoro?
|
|
377
380
|
error_message: Messaggio di errore
|
data/config/locales/ja.yml
CHANGED
|
@@ -19,10 +19,10 @@ ja:
|
|
|
19
19
|
completed: 完了
|
|
20
20
|
created_at: 作成日時
|
|
21
21
|
details: 詳細
|
|
22
|
-
|
|
22
|
+
failed: 失敗
|
|
23
23
|
finished_at: 完了日時
|
|
24
24
|
not_found: バッチが見つかりません
|
|
25
|
-
|
|
25
|
+
on_failure: 失敗時
|
|
26
26
|
on_finish: 完了時
|
|
27
27
|
on_success: 成功時
|
|
28
28
|
progress: 進捗
|
|
@@ -131,6 +131,7 @@ ja:
|
|
|
131
131
|
total_label: デッドレターキュー内のメッセージ
|
|
132
132
|
show:
|
|
133
133
|
back: DLQに戻る
|
|
134
|
+
context: コンテキスト
|
|
134
135
|
discard: 破棄
|
|
135
136
|
discard_confirm: 完全に破棄しますか?
|
|
136
137
|
headers: ヘッダー
|
|
@@ -194,6 +195,7 @@ ja:
|
|
|
194
195
|
title: イベント
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: ペイロード
|
|
198
|
+
context: コンテキスト
|
|
197
199
|
discard: 破棄
|
|
198
200
|
discard_confirm: このイベントを破棄しますか?アーカイブされます。
|
|
199
201
|
edit_payload: 編集して再試行
|
|
@@ -372,6 +374,7 @@ ja:
|
|
|
372
374
|
show:
|
|
373
375
|
back: ジョブに戻る
|
|
374
376
|
backtrace: バックトレース
|
|
377
|
+
context: コンテキスト
|
|
375
378
|
discard: 破棄
|
|
376
379
|
discard_confirm: このジョブを完全に破棄しますか?
|
|
377
380
|
error_message: エラーメッセージ
|
data/config/locales/nb.yml
CHANGED
|
@@ -19,10 +19,10 @@ nb:
|
|
|
19
19
|
completed: Fullført
|
|
20
20
|
created_at: Opprettet den
|
|
21
21
|
details: Detaljer
|
|
22
|
-
|
|
22
|
+
failed: Mislyktes
|
|
23
23
|
finished_at: Avsluttet den
|
|
24
24
|
not_found: Gruppe ikke funnet
|
|
25
|
-
|
|
25
|
+
on_failure: Ved feil
|
|
26
26
|
on_finish: Ved avslutning
|
|
27
27
|
on_success: Ved suksess
|
|
28
28
|
progress: Fremdrift
|
|
@@ -131,6 +131,7 @@ nb:
|
|
|
131
131
|
total_label: meldinger i dead letter-kø
|
|
132
132
|
show:
|
|
133
133
|
back: Tilbake til DLQ
|
|
134
|
+
context: Kontekst
|
|
134
135
|
discard: Forkast
|
|
135
136
|
discard_confirm: Forkaste permanent?
|
|
136
137
|
headers: Overskrifter
|
|
@@ -194,6 +195,7 @@ nb:
|
|
|
194
195
|
title: Hendelser
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Nyttelast
|
|
198
|
+
context: Kontekst
|
|
197
199
|
discard: Forkast
|
|
198
200
|
discard_confirm: Forkast denne hendelsen? Den vil bli arkivert.
|
|
199
201
|
edit_payload: Rediger & prøv på nytt
|
|
@@ -372,6 +374,7 @@ nb:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Tilbake til jobber
|
|
374
376
|
backtrace: Tilbakekalling
|
|
377
|
+
context: Kontekst
|
|
375
378
|
discard: Forkast
|
|
376
379
|
discard_confirm: Slett denne jobben permanent?
|
|
377
380
|
error_message: Feilmelding
|
data/config/locales/nl.yml
CHANGED
|
@@ -19,10 +19,10 @@ nl:
|
|
|
19
19
|
completed: Voltooid
|
|
20
20
|
created_at: Aangemaakt op
|
|
21
21
|
details: Details
|
|
22
|
-
|
|
22
|
+
failed: Mislukt
|
|
23
23
|
finished_at: Voltooid op
|
|
24
24
|
not_found: Groep niet gevonden
|
|
25
|
-
|
|
25
|
+
on_failure: Bij mislukking
|
|
26
26
|
on_finish: Bij voltooiing
|
|
27
27
|
on_success: Bij succes
|
|
28
28
|
progress: Voortgang
|
|
@@ -131,6 +131,7 @@ nl:
|
|
|
131
131
|
total_label: berichten in dead letter-wachtrij
|
|
132
132
|
show:
|
|
133
133
|
back: Terug naar DLQ
|
|
134
|
+
context: Context
|
|
134
135
|
discard: Verwerpen
|
|
135
136
|
discard_confirm: Permanent verwerpen?
|
|
136
137
|
headers: Headers
|
|
@@ -194,6 +195,7 @@ nl:
|
|
|
194
195
|
title: Gebeurtenissen
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Payload
|
|
198
|
+
context: Context
|
|
197
199
|
discard: Verwijderen
|
|
198
200
|
discard_confirm: Deze gebeurtenis verwijderen? Deze wordt gearchiveerd.
|
|
199
201
|
edit_payload: Bewerken & Opnieuw Proberen
|
|
@@ -372,6 +374,7 @@ nl:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Terug naar Taken
|
|
374
376
|
backtrace: Stacktrace
|
|
377
|
+
context: Context
|
|
375
378
|
discard: Verwijderen
|
|
376
379
|
discard_confirm: Deze taak permanent verwijderen?
|
|
377
380
|
error_message: Foutmelding
|
data/config/locales/pt.yml
CHANGED
|
@@ -19,10 +19,10 @@ pt:
|
|
|
19
19
|
completed: Concluídos
|
|
20
20
|
created_at: Criado em
|
|
21
21
|
details: Detalhes
|
|
22
|
-
|
|
22
|
+
failed: Falhados
|
|
23
23
|
finished_at: Finalizado em
|
|
24
24
|
not_found: Lote não encontrado
|
|
25
|
-
|
|
25
|
+
on_failure: Ao falhar
|
|
26
26
|
on_finish: Ao finalizar
|
|
27
27
|
on_success: Ao ter sucesso
|
|
28
28
|
progress: Progresso
|
|
@@ -131,6 +131,7 @@ pt:
|
|
|
131
131
|
total_label: mensagens na fila de mensagens mortas
|
|
132
132
|
show:
|
|
133
133
|
back: Voltar para DLQ
|
|
134
|
+
context: Contexto
|
|
134
135
|
discard: Descartar
|
|
135
136
|
discard_confirm: Descartar permanentemente?
|
|
136
137
|
headers: Cabeçalhos
|
|
@@ -194,6 +195,7 @@ pt:
|
|
|
194
195
|
title: Eventos
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Payload
|
|
198
|
+
context: Contexto
|
|
197
199
|
discard: Descartar
|
|
198
200
|
discard_confirm: Descartar este evento? Ele será arquivado.
|
|
199
201
|
edit_payload: Editar e Tentar Novamente
|
|
@@ -372,6 +374,7 @@ pt:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Voltar para Trabalhos
|
|
374
376
|
backtrace: Rastreamento de Pilha
|
|
377
|
+
context: Contexto
|
|
375
378
|
discard: Descartar
|
|
376
379
|
discard_confirm: Descartar este trabalho permanentemente?
|
|
377
380
|
error_message: Mensagem de Erro
|
data/config/locales/sv.yml
CHANGED
|
@@ -19,10 +19,10 @@ sv:
|
|
|
19
19
|
completed: Slutförda
|
|
20
20
|
created_at: Skapad den
|
|
21
21
|
details: Detaljer
|
|
22
|
-
|
|
22
|
+
failed: Misslyckades
|
|
23
23
|
finished_at: Avslutad den
|
|
24
24
|
not_found: Grupp hittades inte
|
|
25
|
-
|
|
25
|
+
on_failure: Vid misslyckande
|
|
26
26
|
on_finish: Vid avslut
|
|
27
27
|
on_success: Vid framgång
|
|
28
28
|
progress: Framsteg
|
|
@@ -131,6 +131,7 @@ sv:
|
|
|
131
131
|
total_label: meddelanden i dead letter-kö
|
|
132
132
|
show:
|
|
133
133
|
back: Tillbaka till DLQ
|
|
134
|
+
context: Kontext
|
|
134
135
|
discard: Kassera
|
|
135
136
|
discard_confirm: Kassera permanent?
|
|
136
137
|
headers: Rubriker
|
|
@@ -194,6 +195,7 @@ sv:
|
|
|
194
195
|
title: Händelser
|
|
195
196
|
pending_table:
|
|
196
197
|
arguments: Payload
|
|
198
|
+
context: Kontext
|
|
197
199
|
discard: Kassera
|
|
198
200
|
discard_confirm: Kassera denna händelse? Den kommer att arkiveras.
|
|
199
201
|
edit_payload: Redigera & Försök igen
|
|
@@ -372,6 +374,7 @@ sv:
|
|
|
372
374
|
show:
|
|
373
375
|
back: Tillbaka till jobb
|
|
374
376
|
backtrace: Backtrace
|
|
377
|
+
context: Kontext
|
|
375
378
|
discard: Kassera
|
|
376
379
|
discard_confirm: Kassera detta jobb permanent?
|
|
377
380
|
error_message: Felmeddelande
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails/generators/active_record"
|
|
5
|
+
require_relative "migration_path"
|
|
6
|
+
|
|
7
|
+
module Pgbus
|
|
8
|
+
module Generators
|
|
9
|
+
class AddBatchCallbackJobsGenerator < Rails::Generators::Base
|
|
10
|
+
include ActiveRecord::Generators::Migration
|
|
11
|
+
include MigrationPath
|
|
12
|
+
|
|
13
|
+
source_root File.expand_path("templates", __dir__)
|
|
14
|
+
|
|
15
|
+
desc "Add jsonb callback-job columns to pgbus_batches (issue #415)"
|
|
16
|
+
|
|
17
|
+
class_option :database,
|
|
18
|
+
type: :string,
|
|
19
|
+
default: nil,
|
|
20
|
+
desc: "Use a separate database for pgbus tables (e.g. --database=pgbus)"
|
|
21
|
+
|
|
22
|
+
def create_migration_file
|
|
23
|
+
migration_template "add_batch_callback_jobs.rb.erb",
|
|
24
|
+
File.join(pgbus_migrate_path, "add_pgbus_batch_callback_jobs.rb")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def display_post_install
|
|
28
|
+
say ""
|
|
29
|
+
say "Pgbus configured batch callbacks installed!", :green
|
|
30
|
+
say ""
|
|
31
|
+
say "Next steps:"
|
|
32
|
+
say " 1. Run: rails db:migrate#{migrate_command_suffix}"
|
|
33
|
+
say " 2. Restart pgbus: bin/pgbus start"
|
|
34
|
+
say ""
|
|
35
|
+
say "You can now pass a configured ActiveJob instance to a batch:"
|
|
36
|
+
say " Pgbus::Batch.new(on_finish: ReportJob.new.set(queue: :critical, wait: 5.minutes))"
|
|
37
|
+
say ""
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def migration_version
|
|
43
|
+
"[#{ActiveRecord::Migration.current_version}]"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails/generators/active_record"
|
|
5
|
+
require_relative "migration_path"
|
|
6
|
+
|
|
7
|
+
module Pgbus
|
|
8
|
+
module Generators
|
|
9
|
+
class AddBatchExecutionsGenerator < Rails::Generators::Base
|
|
10
|
+
include ActiveRecord::Generators::Migration
|
|
11
|
+
include MigrationPath
|
|
12
|
+
|
|
13
|
+
source_root File.expand_path("templates", __dir__)
|
|
14
|
+
|
|
15
|
+
desc "Add pgbus_batch_executions and rename batch failure columns (issue #414)"
|
|
16
|
+
|
|
17
|
+
class_option :database,
|
|
18
|
+
type: :string,
|
|
19
|
+
default: nil,
|
|
20
|
+
desc: "Use a separate database for pgbus tables (e.g. --database=pgbus)"
|
|
21
|
+
|
|
22
|
+
def create_migration_file
|
|
23
|
+
migration_template "add_batch_executions.rb.erb",
|
|
24
|
+
File.join(pgbus_migrate_path, "add_pgbus_batch_executions.rb")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def display_post_install
|
|
28
|
+
say ""
|
|
29
|
+
say "Pgbus batch execution-row tracking installed!", :green
|
|
30
|
+
say ""
|
|
31
|
+
say "Next steps:"
|
|
32
|
+
say " 1. Run: rails db:migrate#{migrate_command_suffix}"
|
|
33
|
+
say " 2. Restart pgbus: bin/pgbus start"
|
|
34
|
+
say ""
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def migration_version
|
|
40
|
+
"[#{ActiveRecord::Migration.current_version}]"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class AddPgbusBatchCallbackJobs < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def up
|
|
3
|
+
add_column :pgbus_batches, :on_finish_job, :jsonb unless column_exists?(:pgbus_batches, :on_finish_job)
|
|
4
|
+
add_column :pgbus_batches, :on_success_job, :jsonb unless column_exists?(:pgbus_batches, :on_success_job)
|
|
5
|
+
add_column :pgbus_batches, :on_failure_job, :jsonb unless column_exists?(:pgbus_batches, :on_failure_job)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def down
|
|
9
|
+
remove_column :pgbus_batches, :on_finish_job if column_exists?(:pgbus_batches, :on_finish_job)
|
|
10
|
+
remove_column :pgbus_batches, :on_success_job if column_exists?(:pgbus_batches, :on_success_job)
|
|
11
|
+
remove_column :pgbus_batches, :on_failure_job if column_exists?(:pgbus_batches, :on_failure_job)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class AddPgbusBatchExecutions < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
+
def up
|
|
3
|
+
create_table :pgbus_batch_executions do |t|
|
|
4
|
+
t.string :batch_id, null: false
|
|
5
|
+
t.string :job_id, null: false
|
|
6
|
+
t.bigint :msg_id
|
|
7
|
+
t.string :queue_name
|
|
8
|
+
t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
add_index :pgbus_batch_executions, :job_id,
|
|
12
|
+
unique: true, name: "idx_pgbus_batch_executions_job_id"
|
|
13
|
+
add_index :pgbus_batch_executions, :batch_id,
|
|
14
|
+
name: "idx_pgbus_batch_executions_batch_id"
|
|
15
|
+
add_index :pgbus_batch_executions, :created_at,
|
|
16
|
+
where: "msg_id IS NULL",
|
|
17
|
+
name: "idx_pgbus_batch_executions_orphans"
|
|
18
|
+
add_foreign_key :pgbus_batch_executions, :pgbus_batches,
|
|
19
|
+
column: :batch_id, primary_key: :batch_id, on_delete: :cascade
|
|
20
|
+
|
|
21
|
+
if column_exists?(:pgbus_batches, :on_discard_class) && !column_exists?(:pgbus_batches, :on_failure_class)
|
|
22
|
+
rename_column :pgbus_batches, :on_discard_class, :on_failure_class
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Drain/restart pgbus workers after this migration: a process that still
|
|
26
|
+
# writes discarded_jobs will error once the column is gone.
|
|
27
|
+
if column_exists?(:pgbus_batches, :discarded_jobs)
|
|
28
|
+
if column_exists?(:pgbus_batches, :failed_jobs)
|
|
29
|
+
execute "UPDATE pgbus_batches SET failed_jobs = failed_jobs + discarded_jobs"
|
|
30
|
+
remove_column :pgbus_batches, :discarded_jobs
|
|
31
|
+
else
|
|
32
|
+
rename_column :pgbus_batches, :discarded_jobs, :failed_jobs
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def down
|
|
38
|
+
unless column_exists?(:pgbus_batches, :discarded_jobs)
|
|
39
|
+
add_column :pgbus_batches, :discarded_jobs, :integer, null: false, default: 0
|
|
40
|
+
if column_exists?(:pgbus_batches, :failed_jobs)
|
|
41
|
+
execute "UPDATE pgbus_batches SET discarded_jobs = failed_jobs"
|
|
42
|
+
execute "UPDATE pgbus_batches SET failed_jobs = 0"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
if column_exists?(:pgbus_batches, :on_failure_class) && !column_exists?(:pgbus_batches, :on_discard_class)
|
|
46
|
+
rename_column :pgbus_batches, :on_failure_class, :on_discard_class
|
|
47
|
+
end
|
|
48
|
+
drop_table :pgbus_batch_executions if table_exists?(:pgbus_batch_executions)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -44,6 +44,8 @@ Pgbus.configure do |c|
|
|
|
44
44
|
|
|
45
45
|
# --- Dispatcher (maintenance tasks) ------------------------------------
|
|
46
46
|
# c.dispatch_interval = 1.0
|
|
47
|
+
# c.batch_retention = 7.days # finished-batch cleanup; nil disables
|
|
48
|
+
# c.batch_sweep_interval = 5.minutes # stalled-batch repair sweep
|
|
47
49
|
|
|
48
50
|
# --- Realtime broadcast isolation (turbo-rails) ------------------------
|
|
49
51
|
# Route turbo-rails' async render+broadcast jobs to a dedicated queue so a
|
|
@@ -104,12 +104,14 @@ class CreatePgbusTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
104
104
|
t.string :description
|
|
105
105
|
t.string :on_finish_class
|
|
106
106
|
t.string :on_success_class
|
|
107
|
-
t.string :
|
|
107
|
+
t.string :on_failure_class
|
|
108
|
+
t.jsonb :on_finish_job
|
|
109
|
+
t.jsonb :on_success_job
|
|
110
|
+
t.jsonb :on_failure_job
|
|
108
111
|
t.jsonb :properties, default: {}
|
|
109
112
|
t.integer :total_jobs, null: false, default: 0
|
|
110
113
|
t.integer :completed_jobs, null: false, default: 0
|
|
111
114
|
t.integer :failed_jobs, null: false, default: 0
|
|
112
|
-
t.integer :discarded_jobs, null: false, default: 0
|
|
113
115
|
t.string :status, null: false, default: "pending"
|
|
114
116
|
t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
|
115
117
|
t.datetime :finished_at
|
|
@@ -120,6 +122,24 @@ class CreatePgbusTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
120
122
|
add_index :pgbus_batches, :status,
|
|
121
123
|
name: "idx_pgbus_batches_status"
|
|
122
124
|
|
|
125
|
+
create_table :pgbus_batch_executions do |t|
|
|
126
|
+
t.string :batch_id, null: false
|
|
127
|
+
t.string :job_id, null: false
|
|
128
|
+
t.bigint :msg_id
|
|
129
|
+
t.string :queue_name
|
|
130
|
+
t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
add_index :pgbus_batch_executions, :job_id,
|
|
134
|
+
unique: true, name: "idx_pgbus_batch_executions_job_id"
|
|
135
|
+
add_index :pgbus_batch_executions, :batch_id,
|
|
136
|
+
name: "idx_pgbus_batch_executions_batch_id"
|
|
137
|
+
add_index :pgbus_batch_executions, :created_at,
|
|
138
|
+
where: "msg_id IS NULL",
|
|
139
|
+
name: "idx_pgbus_batch_executions_orphans"
|
|
140
|
+
add_foreign_key :pgbus_batch_executions, :pgbus_batches,
|
|
141
|
+
column: :batch_id, primary_key: :batch_id, on_delete: :cascade
|
|
142
|
+
|
|
123
143
|
# Recurring task definitions (synced from config/recurring.yml)
|
|
124
144
|
create_table :pgbus_recurring_tasks do |t|
|
|
125
145
|
t.string :key, null: false
|
|
@@ -186,6 +206,7 @@ class CreatePgbusTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
186
206
|
drop_table :pgbus_stream_queues
|
|
187
207
|
drop_table :pgbus_recurring_executions
|
|
188
208
|
drop_table :pgbus_recurring_tasks
|
|
209
|
+
drop_table :pgbus_batch_executions
|
|
189
210
|
drop_table :pgbus_batches
|
|
190
211
|
drop_table :pgbus_blocked_executions
|
|
191
212
|
drop_table :pgbus_semaphores
|