Class: Hibiki::Rails::GraphActor

Inherits:
Object
  • Object
show all
Defined in:
lib/hibiki/rails/graph_actor.rb

Overview

Funnels all access to one connection's signal graph through a single worker thread. ActionCable dispatches incoming commands on a thread pool with no per-channel ordering guarantee, while hibiki's threading model is confinement without locks — so the graph is built, mutated, and disposed on exactly one thread, and cable threads only ever enqueue closures.

Thread-per-graph is deliberate while the gem incubates; a pooled executor with per-graph ordering can replace it behind Channel#build_graph_actor once real numbers ask for one.

Instance Method Summary collapse

Constructor Details

#initialize(name: "hibiki-graph", on_error: Hibiki::Rails.default_error_reporter) ⇒ GraphActor

Returns a new instance of GraphActor.



16
17
18
19
20
21
# File 'lib/hibiki/rails/graph_actor.rb', line 16

def initialize(name: "hibiki-graph", on_error: Hibiki::Rails.default_error_reporter)
  @on_error = on_error
  @queue = Queue.new
  @thread = Thread.new { work }
  @thread.name = name # keep <= 15 chars: Linux truncates pthread names
end

Instance Method Details

#post(&job) ⇒ Object

Enqueue a closure for the worker. Returns false (rather than raising) once stopped: an action can race teardown, and a cable thread must never blow up because the user just navigated away.



26
27
28
29
30
31
# File 'lib/hibiki/rails/graph_actor.rb', line 26

def post(&job)
  @queue << job
  true
rescue ClosedQueueError
  false
end

#stop(wait: false) ⇒ Object

Queue#close, not clear: already-posted jobs — in particular the root dispose posted from unsubscribed — drain before the worker exits. Idempotent. wait: true joins the worker; specs use it as a deterministic drain barrier.



37
38
39
40
41
# File 'lib/hibiki/rails/graph_actor.rb', line 37

def stop(wait: false)
  @queue.close
  @thread.join if wait
  nil
end

#stopped?Boolean

Returns:

  • (Boolean)


43
# File 'lib/hibiki/rails/graph_actor.rb', line 43

def stopped? = @queue.closed?