Class: Lich::Gemstone::Combat::AsyncProcessor

Inherits:
Object
  • Object
show all
Defined in:
documented/gemstone/combat/async_processor.rb

Overview

Note:

Processing is intentionally single-threaded despite the max_threads parameter.

Single-threaded worker that processes combat chunks in FIFO order from a queue.

Chunks are enqueued from the game stream thread via #process_async, which never blocks. A dedicated worker thread dequeues and processes chunks sequentially, preserving event ordering required for accurate status tracking, UCS updates, and damage attribution. Since all mutation of creature instances happens on one thread, no synchronization is needed within Creature/CreatureInstance classes.

Instance Method Summary collapse

Constructor Details

#initialize(_max_threads = 1) ⇒ AsyncProcessor

max_threads retained for call-site compatibility; processing is intentionally single-threaded to preserve event ordering.



33
34
35
36
37
38
# File 'documented/gemstone/combat/async_processor.rb', line 33

def initialize(_max_threads = 1)
  @queue = Queue.new
  @processing = false
  @chunks_processed = 0
  @worker = Thread.new { run_loop }
end

Instance Method Details

#process_async(chunk) ⇒ Object

Enqueue a chunk; O(1), never blocks the game stream.



41
42
43
44
45
# File 'documented/gemstone/combat/async_processor.rb', line 41

def process_async(chunk)
  return if chunk.empty?
  @queue.push(chunk)
  nil
end

#shutdownObject

Drain remaining work and stop the worker.



48
49
50
51
52
53
54
55
56
57
58
# File 'documented/gemstone/combat/async_processor.rb', line 48

def shutdown
  respond "[Combat] Waiting for #{@queue.size} queued chunks..." if Tracker.debug?
  @queue.push(:shutdown)
  @worker.join

  # Force GC after shutdown to help with memory fragmentation.
  # Compaction is routed through Lich::Util::GtkCompaction, which
  # keeps it safe to use alongside gtk3.
  GC.start
  Lich::Util::GtkCompaction.safe_compact!
end

#statsHash

Returns a snapshot of the processor's workload and health.

Examples:

processor.stats #=> {active: 0, queued: 3, total: 1205, worker_alive: true}

Returns:

  • (Hash)

    with keys :active (1 if processing, 0 otherwise), :queued (pending chunks), :total (cumulative chunks processed), :worker_alive (whether the worker thread is running)



66
67
68
69
70
71
72
73
# File 'documented/gemstone/combat/async_processor.rb', line 66

def stats
  {
    active: @processing ? 1 : 0,
    queued: @queue.size,
    total: @chunks_processed,
    worker_alive: @worker.alive?
  }
end