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

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

Overview

Asynchronous combat event processor

Processes combat events in parallel using a thread pool for improved performance during large combat encounters. Uses atomic operations for thread-safe tracking.

Examples:

Basic usage

processor = AsyncProcessor.new(max_threads: 2)
processor.process_async(combat_lines)
processor.shutdown  # Wait for all threads to complete

Instance Method Summary collapse

Constructor Details

#initialize(max_threads = 2) ⇒ AsyncProcessor

Initialize async processor

Parameters:

  • max_threads (Integer) (defaults to: 2)

    Maximum number of concurrent processing threads



27
28
29
30
31
# File 'documented/gemstone/combat/async_processor.rb', line 27

def initialize(max_threads = 2)
  @max_threads = max_threads
  @active_count = Concurrent::AtomicFixnum.new(0)
  @thread_pool = []
end

Instance Method Details

#process_async(chunk) ⇒ Thread?

Process a chunk of combat lines asynchronously

Spawns a new thread to process the chunk if capacity allows. Waits if thread pool is at max capacity.

Parameters:

  • chunk (Array<String>)

    Array of game lines to process

Returns:

  • (Thread, nil)

    The processing thread or nil if chunk was empty



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'documented/gemstone/combat/async_processor.rb', line 40

def process_async(chunk)
  return if chunk.empty?

  # Clean up dead threads
  @thread_pool.reject!(&:alive?)

  # Wait if at capacity
  while @active_count.value >= @max_threads
    sleep(0.01)
  end

  @active_count.increment

  thread = Thread.new do
    begin
      Thread.current[:start_time] = Time.now
      Thread.current[:line_count] = chunk.size

      Processor.process(chunk)

      elapsed = Time.now - Thread.current[:start_time]
      if elapsed > 0.5 && Tracker.debug?
        puts "[Combat] Processed #{chunk.size} lines in #{elapsed.round(3)}s"
      end
    rescue => e
      puts "[Combat] Processing error: #{e.message}" if Tracker.debug?
      puts e.backtrace.first(3) if Tracker.debug?
    ensure
      @active_count.decrement
    end
  end

  @thread_pool << thread
  thread
end

#shutdownvoid

This method returns an undefined value.

Shutdown the processor and wait for all threads to complete

Blocks until all active processing threads finish.



81
82
83
84
85
# File 'documented/gemstone/combat/async_processor.rb', line 81

def shutdown
  puts "[Combat] Waiting for #{@thread_pool.count(&:alive?)} threads..." if Tracker.debug?
  @thread_pool.each(&:join)
  @thread_pool.clear
end

#statsHash

Get current processing statistics

Returns:

  • (Hash)

    Stats including :active, :total, :max_threads, :processing



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'documented/gemstone/combat/async_processor.rb', line 90

def stats
  {
    active: @active_count.value,
    total: @thread_pool.count(&:alive?),
    max_threads: @max_threads,
    processing: @thread_pool.select(&:alive?).map do |thread|
      {
        lines: thread[:line_count] || 0,
        elapsed: thread[:start_time] ? (Time.now - thread[:start_time]).round(2) : 0
      }
    end
  }
end