Class: Lich::Gemstone::Combat::AsyncProcessor
- Inherits:
-
Object
- Object
- Lich::Gemstone::Combat::AsyncProcessor
- Defined in:
- documented/gemstone/combat/async_processor.rb
Overview
Async Combat Processor - Thread-safe combat processing for performance
This class manages asynchronous processing of combat actions using a thread pool. It ensures thread safety and efficient resource management.
Instance Method Summary collapse
-
#initialize(max_threads = 2) ⇒ AsyncProcessor
constructor
Initializes a new AsyncProcessor instance.
-
#process_async(chunk) ⇒ Thread
Processes a chunk of combat actions asynchronously.
-
#shutdown ⇒ void
Shuts down the AsyncProcessor, waiting for all threads to finish.
-
#stats ⇒ Hash
Returns statistics about the current state of the AsyncProcessor.
Constructor Details
#initialize(max_threads = 2) ⇒ AsyncProcessor
Initializes a new AsyncProcessor instance.
23 24 25 26 27 28 29 |
# File 'documented/gemstone/combat/async_processor.rb', line 23 def initialize(max_threads = 2) @max_threads = max_threads @active_count = Concurrent::AtomicFixnum.new(0) @thread_pool = [] @last_cleanup = Time.now @last_compact = Time.now end |
Instance Method Details
#process_async(chunk) ⇒ Thread
Processes a chunk of combat actions asynchronously.
38 39 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 75 |
# File 'documented/gemstone/combat/async_processor.rb', line 38 def process_async(chunk) return if chunk.empty? # Periodic cleanup of dead threads (safety net) cleanup_dead_threads if Time.now - @last_cleanup > 30 # Wait if at capacity while @active_count.value >= @max_threads sleep(0.01) end @active_count.increment # Create thread and store reference for self-cleanup 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? respond "[Combat] Processed #{chunk.size} lines in #{elapsed.round(3)}s" end rescue => e respond "[Combat] Processing error: #{e.}" if Tracker.debug? respond e.backtrace.first(3) if Tracker.debug? ensure @active_count.decrement # Thread cleans itself up from pool when done (use Thread.current to avoid race) @thread_pool.delete(Thread.current) end end @thread_pool << thread thread end |
#shutdown ⇒ void
This method returns an undefined value.
Shuts down the AsyncProcessor, waiting for all threads to finish.
82 83 84 85 86 87 88 89 90 |
# File 'documented/gemstone/combat/async_processor.rb', line 82 def shutdown respond "[Combat] Waiting for #{@thread_pool.count(&:alive?)} threads..." if Tracker.debug? @thread_pool.each(&:join) @thread_pool.clear # Force GC after shutdown to help with memory fragmentation GC.start GC.compact if GC.respond_to?(:compact) # Ruby 2.7+ end |
#stats ⇒ Hash
Returns statistics about the current state of the AsyncProcessor.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'documented/gemstone/combat/async_processor.rb', line 97 def stats { active: @active_count.value, total_alive: @thread_pool.count(&:alive?), pool_size: @thread_pool.size, # ACTUAL array size (includes dead threads if not cleaned) dead_threads: @thread_pool.count { |t| !t.alive? }, # Count dead threads still in pool 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 |