Class: Capybara::Lightpanda::Client::Subscriber

Inherits:
Object
  • Object
show all
Defined in:
lib/capybara/lightpanda/client/subscriber.rb

Constant Summary collapse

DEFAULT_ON_ERROR =

Default error sink: write a one-line warning so a misbehaving handler is visible without crashing the CDP message thread. Tests can inject a custom proc via ‘on_error:` to capture failures.

lambda do |event, error|
  warn("[capybara-lightpanda] subscriber callback for #{event.inspect} raised " \
       "#{error.class}: #{error.message}")
end

Instance Method Summary collapse

Constructor Details

#initialize(on_error: DEFAULT_ON_ERROR) ⇒ Subscriber

Returns a new instance of Subscriber.



15
16
17
18
19
# File 'lib/capybara/lightpanda/client/subscriber.rb', line 15

def initialize(on_error: DEFAULT_ON_ERROR)
  @subscriptions = Hash.new { |h, k| h[k] = [] }
  @mutex = Mutex.new
  @on_error = on_error
end

Instance Method Details

#clearObject



65
66
67
# File 'lib/capybara/lightpanda/client/subscriber.rb', line 65

def clear
  @mutex.synchronize { @subscriptions.clear }
end

#dispatch(event, params) ⇒ Object

Run every callback registered for ‘event`. Exceptions in one callback must not stop the others or propagate out — the message thread sets `abort_on_exception = true`, so an unhandled raise would tear down the entire CDP connection.

Two layers of rescue:

1. The callback itself may raise — route to @on_error.
2. @on_error itself may raise (custom hook, broken stderr) —
   swallow at the last level so the dispatch loop survives.


46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/capybara/lightpanda/client/subscriber.rb', line 46

def dispatch(event, params)
  callbacks = @mutex.synchronize { @subscriptions[event].dup }

  callbacks.each do |callback|
    callback.call(params)
  rescue StandardError => e
    begin
      @on_error.call(event, e)
    rescue StandardError
      # The error sink failed — nothing to do but keep going. We
      # cannot log here without re-entering the broken path.
    end
  end
end

#subscribe(event, &block) ⇒ Object



21
22
23
24
25
# File 'lib/capybara/lightpanda/client/subscriber.rb', line 21

def subscribe(event, &block)
  @mutex.synchronize do
    @subscriptions[event] << block
  end
end

#subscribed?(event) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/capybara/lightpanda/client/subscriber.rb', line 61

def subscribed?(event)
  @mutex.synchronize { @subscriptions.key?(event) && @subscriptions[event].any? }
end

#unsubscribe(event, block = nil) ⇒ Object



27
28
29
30
31
32
33
34
35
# File 'lib/capybara/lightpanda/client/subscriber.rb', line 27

def unsubscribe(event, block = nil)
  @mutex.synchronize do
    if block
      @subscriptions[event].delete(block)
    else
      @subscriptions.delete(event)
    end
  end
end