Skip to content

fix(ruby): drain backlog and reconnect after transient database errors #313

Description

@NikolayS

Severity

High — new 0.3 Ruby client reliability and throughput.

Problems

The Ruby Pgque::Consumer loop has two coupled defects:

  1. It waits poll_interval after every successfully processed batch. If several batches already existed before the consumer connected, their notifications are stale, so backlog drains at one batch per interval.
  2. It has no recovery loop around connect/LISTEN/receive/ack database failures. A transient PG::Error or Pgque::Error exits start permanently, despite the README contract that start blocks until stopped/signaled.

Reproductions

Backlog:

  • pre-create three ticked batches;
  • start Ruby Consumer with poll_interval: 2;
  • observed handler gaps: [2.03, 2.01].

Connection failure:

c = Pgque::Consumer.new(
  "host=127.0.0.1 port=1 dbname=x connect_timeout=1",
  queue: "q", name: "c", poll_interval: 0.01
)
c.start

Observed: PG::ConnectionBad escapes and running? == false.

Affected file: clients/ruby/lib/pgque/consumer.rb.

Expected fix

  • Make one poll iteration report whether it completed/acked a non-empty batch.
  • Re-poll immediately after completed work; wait only after an empty or intentionally unfinished batch.
  • Add a reconnecting outer loop for PG::Error / Pgque::Error, close the failed session, wait in stop-aware slices, reconnect and re-LISTEN.
  • Preserve handler/nack containment, unexpected-error propagation, prompt stop, and signal safety.

Regression coverage should include three-batch drain with a long interval, initial connect failure then success, transient receive error, terminated-backend recovery, and prompt stop during retry wait.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions