Class: Pgbus::EventBus::Registry

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/pgbus/event_bus/registry.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRegistry

Returns a new instance of Registry.



12
13
14
15
# File 'lib/pgbus/event_bus/registry.rb', line 12

def initialize
  @subscribers = []
  @mutex = Mutex.new
end

Instance Attribute Details

#subscribersObject (readonly)

Returns the value of attribute subscribers.



10
11
12
# File 'lib/pgbus/event_bus/registry.rb', line 10

def subscribers
  @subscribers
end

Instance Method Details

#clear!Object



79
80
81
# File 'lib/pgbus/event_bus/registry.rb', line 79

def clear!
  @mutex.synchronize { @subscribers.clear }
end

#event_queue_namesObject

Physical PGMQ queue names for every registered event subscriber, so a wildcard (queues: ['*']) worker can exclude them — an event queue carries event payloads, not ActiveJob jobs, and a job worker that adopts one fails to deserialize and DLQ-moves the event (issue #333). Returns a Set of prefixed names (#{queue_prefix}_<subscriber>), matching the pgmq.meta rows the wildcard resolver diffs against.



75
76
77
# File 'lib/pgbus/event_bus/registry.rb', line 75

def event_queue_names
  @subscribers.to_set { |s| Pgbus.configuration.queue_name(s.queue_name) }
end

#handlers_for(routing_key) ⇒ Object



65
66
67
# File 'lib/pgbus/event_bus/registry.rb', line 65

def handlers_for(routing_key)
  @subscribers.select { |s| matches?(s.pattern, routing_key) }
end

#setup_all!(safe: false) ⇒ Object

Set up every registered subscriber (creates its queue + binds its topic via Pgbus.client, which opens a PGMQ connection).

safe: false (default) — set up unconditionally; a connection error propagates. Use when you know the database is up. safe: true — boot/rake-safe: skip entirely in a schema/db: rake context (opening a PGMQ connection there would block DROP DATABASE and isn't wanted during schema load / asset precompile), and swallow a connection error with a warning instead of crashing boot when the DB isn't ready. This is the path host apps should call from an initializer so they stop hand-wrapping setup_all! in a multi-class rescue (issue #334).



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/pgbus/event_bus/registry.rb', line 42

def setup_all!(safe: false)
  return if safe && schema_task_context?

  # Snapshot under the mutex — subscribe/clear! mutate @subscribers under
  # @mutex, and setup! does DB I/O we must NOT hold the lock across, so
  # iterate a copy taken atomically.
  subscribers = @mutex.synchronize { @subscribers.dup }

  subscribers.each do |subscriber|
    subscriber.setup!
  rescue PGMQ::Errors::ConnectionError, PG::ConnectionBad => e
    # Only a genuine CONNECTION failure ("database isn't up yet") is
    # tolerable under safe:; a PG::Error subclass like a syntax/permission/
    # missing-table error is a real setup bug and must still surface.
    raise unless safe

    Pgbus.logger.warn do
      "[Pgbus] EventBus subscriber setup skipped (#{e.class}: #{e.message}) — " \
        "the database isn't reachable yet; subscribers set up on the next attempt."
    end
  end
end

#subscribe(pattern, handler_class, queue_name: nil) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/pgbus/event_bus/registry.rb', line 17

def subscribe(pattern, handler_class, queue_name: nil)
  subscriber = Subscriber.new(
    pattern: pattern,
    handler_class: handler_class,
    queue_name: queue_name
  )

  @mutex.synchronize do
    @subscribers << subscriber
  end

  subscriber
end