Module: Phronomy::ThreadActorRegistry

Defined in:
lib/phronomy/thread_actor_registry.rb

Overview

Global per-thread-id Actor registry.

Maps the +:thread_id+ key from the +config:+ argument passed to Agent::Base#invoke to a Actor instance. Each thread_id gets exactly one Actor so that all operations for the same conversation are serialised automatically.

Examples:

Phronomy::ThreadActorRegistry.for("user-42").call do
  # runs sequentially on the Actor's thread
end

Class Method Summary collapse

Class Method Details

.actor_countInteger

Returns the current number of registered Actors.

Returns:

  • (Integer)


45
46
47
# File 'lib/phronomy/thread_actor_registry.rb', line 45

def actor_count
  @registry_actor.call { @actors.size }
end

.clear_allObject

Stops and removes every registered Actor. Intended for test teardown and process shutdown.



59
60
61
62
# File 'lib/phronomy/thread_actor_registry.rb', line 59

def clear_all
  actors = @registry_actor.call { @actors.values.tap { @actors.clear } }
  actors.each(&:stop)
end

.each_actor {|Phronomy::Actor| ... } ⇒ Object

Yields each currently registered Actor. A snapshot is taken so the registry cannot change while callers iterate.

Yields:



68
69
70
# File 'lib/phronomy/thread_actor_registry.rb', line 68

def each_actor(&block)
  @registry_actor.call { @actors.values.dup }.each(&block)
end

.for(thread_id) ⇒ Phronomy::Actor

Returns (or lazily creates) the Actor for +thread_id+.

When +Phronomy.configuration.max_actors+ is set, the registry evicts the least-recently-used Actor (by stopping it) before inserting a new one. Accessing an existing Actor moves it to the most-recently-used position.

Parameters:

  • thread_id (String)

Returns:



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/phronomy/thread_actor_registry.rb', line 28

def for(thread_id)
  @registry_actor.call do
    if @actors.key?(thread_id)
      # LRU touch: move to end (most-recently used)
      actor = @actors.delete(thread_id)
      @actors[thread_id] = actor
    else
      evict_lru_if_needed!
      @actors[thread_id] = Actor.new
    end
    @actors[thread_id]
  end
end

.stop(thread_id) ⇒ Object

Gracefully stops the Actor for +thread_id+ and removes it from the registry. The next call to for with the same id creates a fresh Actor.

Parameters:

  • thread_id (String)


53
54
55
# File 'lib/phronomy/thread_actor_registry.rb', line 53

def stop(thread_id)
  @registry_actor.call { @actors.delete(thread_id) }&.stop
end