require "agent/queue" require "agent/errors" module Agent class Queue class Unbuffered < Queue attr_reader :waiting_pushes, :waiting_pops def buffered?; false; end def unbuffered?; true; end def push?; @waiting_pops > 0; end def pop?; @waiting_pushes > 0; end protected def reset_custom_state @waiting_pushes = pushes.size @waiting_pops = pops.size end def process operation = operations.last if operation.is_a?(Push) @waiting_pushes += 1 pops.dup.each do |pop_operation| if operation.blocking_once && operation.blocking_once == pop_operation.blocking_once next end error = operation.receive do |value| error = pop_operation.send do value end @waiting_pops -= 1 operations.delete(pop_operation) pops.delete(pop_operation) raise Errors::Rollback if error end if error.nil? || error.message?("already performed") @waiting_pushes -= 1 operations.pop pushes.pop break end end else # Pop @waiting_pops += 1 pushes.dup.each do |push_operation| if operation.blocking_once && operation.blocking_once == push_operation.blocking_once next end error = operation.send do value = nil error = push_operation.receive do |v| value = v end @waiting_pushes -= 1 operations.delete(push_operation) pushes.delete(push_operation) raise Errors::Rollback if error value end if error.nil? || error.message?("already performed") @waiting_pops -= 1 operations.pop pops.pop break end end end end end end end