kenichi / angelo

Sinatra-like DSL for Reel that supports WebSockets and SSE
Other
303 stars 23 forks source link

ArgumentError: this IO is already registered with selector #53

Open mighe opened 9 years ago

mighe commented 9 years ago

This happened a couple of times:

ERROR -- : Actor crashed!
ArgumentError: this IO is already registered with selector
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/reactor.rb:42:in `register'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/reactor.rb:42:in `wait'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/reactor.rb:26:in `wait_writable'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io.rb:65:in `wait_writable'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/stream.rb:33:in `wait_writable'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/stream.rb:63:in `rescue in block in syswrite'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/stream.rb:60:in `block in syswrite'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/stream.rb:389:in `synchronize'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/stream.rb:58:in `syswrite'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/stream.rb:355:in `do_write'
    /xxx/gems/celluloid-io-0.16.2/lib/celluloid/io/stream.rb:256:in `<<'
    /xxx/gems/reel-0.5.0/lib/reel/websocket.rb:80:in `write'
    /yyy/angelo_apis.rb:32:in `block (2 levels) in <class:AngeloApis>'
    /xxx/gems/angelo-0.4.1/lib/angelo/stash.rb:56:in `block in each'
    /xxx/gems/angelo-0.4.1/lib/angelo/stash.rb:54:in `each'
    /xxx/gems/angelo-0.4.1/lib/angelo/stash.rb:54:in `each'
    /yyy/angelo_apis.rb:32:in `block in <class:AngeloApis>'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/calls.rb:26:in `public_send'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/calls.rb:26:in `dispatch'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/calls.rb:122:in `dispatch'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/cell.rb:60:in `block in invoke'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/cell.rb:71:in `block in task'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/actor.rb:357:in `block in task'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/tasks.rb:57:in `block in initialize'
    /xxx/gems/celluloid-0.16.0/lib/celluloid/tasks/task_fiber.rb:15:in `block in create'

calling this task:

  task :custom_event do |event|
    websockets.each { |ws| ws.write event.to_json }
  end

I saw this error a couple of times recently. Do you think it can be an Angelo issue or can it be a problem of one of its dependency? I found this

digitalextremist commented 9 years ago

Let me know what you find on this.

mighe commented 9 years ago

@digitalextremist @kenichi I'm able to reproduce it! :+1:

require 'angelo'
require 'json'

class AngeloStressTest < Angelo::Base

  websocket '/' do |ws|
    websockets << ws
  end

  task :custom_event do |event|
    websockets.each { |ws| ws.write event.to_json }
  end

end

s = AngeloStressTest.run

Thread.new do
  loop do
    sleep(1)
    3.times { s.custom_event( {a: 'hello' * 10E6} ) }
    print '*'
  end
end

puts 'started'

gets

Just run that and open a websocket from your browser. I suspected it was an issue related to heavy traffic, because I first saw this adding components to my backend, with this simple code we're simulating a situation with many events sent fast.

digitalextremist commented 9 years ago

Usually this sort of thing happens when you start multiple server instances on top of each other, but I would need to look further into angelo to fully see the implications of your repro.

kenichi commented 9 years ago

hmm, it seems to be somewhere between 10E4 and 10E5 as the multiplier that the error is raised. prior to that size of message, it seems to work.

the error in question seems to be coming from NIO::Selector#register?

mighe commented 9 years ago

My code production code sends short strings (usually less than 5000 characters), but sometimes I got that error. Probably is somehow related to the (wi-fi) network speed or something like that, in this example I use a big constant to reproduce the issue consistently on localhost