Class: ActionCable::Server::StreamEventLoop
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | actioncable/lib/action_cable/server/stream_event_loop.rb |
Class Method Summary
- .new ⇒ StreamEventLoop constructor
Instance Method Summary
- #attach(io, stream)
- #detach(io, stream)
- #stop
- #writes_pending(io)
- #run private
- #spawn private
- #wakeup private
Constructor Details
.new ⇒ StreamEventLoop
# File 'actioncable/lib/action_cable/server/stream_event_loop.rb', line 10
def initialize @nio = @thread = nil @map = {} @stopping = false @todo = Queue.new @spawn_mutex = Mutex.new end
Instance Method Details
#attach(io, stream)
[ GitHub ]# File 'actioncable/lib/action_cable/server/stream_event_loop.rb', line 19
def attach(io, stream) @todo << lambda do @map[io] = @nio.register(io, :r) @map[io].value = stream end wakeup end
#detach(io, stream)
[ GitHub ]# File 'actioncable/lib/action_cable/server/stream_event_loop.rb', line 27
def detach(io, stream) @todo << lambda do @nio.deregister io @map.delete io io.close end wakeup end
#run (private)
[ GitHub ]# File 'actioncable/lib/action_cable/server/stream_event_loop.rb', line 69
def run loop do if @stopping @nio.close break end until @todo.empty? @todo.pop(true).call end next unless monitors = @nio.select monitors.each do |monitor| io = monitor.io stream = monitor.value begin if monitor.writable? if stream.flush_write_buffer monitor.interests = :r end next unless monitor.readable? end incoming = io.read_nonblock(4096, exception: false) case incoming when :wait_readable next when nil stream.close else stream.receive incoming end rescue # We expect one of EOFError or Errno::ECONNRESET in normal operation (when the # client goes away). But if anything else goes wrong, this is still the best way # to handle it. begin stream.close rescue @nio.deregister io @map.delete io end end end end end
#spawn (private)
[ GitHub ]#stop
[ GitHub ]# File 'actioncable/lib/action_cable/server/stream_event_loop.rb', line 45
def stop @stopping = true wakeup if @nio end
#wakeup (private)
[ GitHub ]# File 'actioncable/lib/action_cable/server/stream_event_loop.rb', line 65
def wakeup spawn || @nio.wakeup end
#writes_pending(io)
[ GitHub ]# File 'actioncable/lib/action_cable/server/stream_event_loop.rb', line 36
def writes_pending(io) @todo << lambda do if monitor = @map[io] monitor.interests = :rw end end wakeup end