imanel/websocket-rack

EM Eventloop & Websocket-Rack

Closed this issue · 2 comments

etm commented

I have a server that is running a background thread, that sends events through a websocket to the client. The thread is stopped and started through an ajax call (not through the websocket), the websocket is up the whole time.

Current thin + websocket-rack + eventmachine 0.12.10

  • everything works as expected

Current thin + websocket-rack + eventmachine 1.0.0.beta.4

  • whenever send is called in the background thread, the sent data is buffered (?) and only is sent to the browser after (a) a timeout of about 30 seconds, or (b) after manually triggering the server (e.g. making calls to different pages of the server or even call wrong locations on the server).

Obviously something with the EM eventloop has changed. Debuging showed that the @socket.send_data (in websocket-rack / lib / rack / websocket / handler / base / connection.rb line 25) is always called correctly (at the right time) and returns immediately just afterwards the data is buffered (?).

Any idea how to best solve this? (e.g. scheduling the next tick in the EM eventloop every time after a send).

cheers. eTM

etm commented

For the record, one solution I found: changing websocket-rack / lib / rack / websocket / handler / base / connection.rb:

def send_data(*args)
  EM.next_tick do
    @socket.send_data(*args)
  end
end

def close_connection(*args)
  EM.next_tick do
    @socket.close_connection(*args)                                                                                                                         
  end
end

solves the problem. But why? Is this good to be included in websocket-rack or am i potentially doing something wrong somewhere else in my scenario.

cheers, eTM.

Hi eTM,

Please excuse me this late reply - lately I have very little time to test things, and this one required much more testing than usual.

The problem was caused because of locking connection between sending data and moving to next method. This was strange at first, but after looking to eventmachine internals it looks that they changed pre-buffer to after-buffer, what resulted in locking state. Adding next_tick solved the problem, and when I think about it it's good that you have found it - it's better this way.

Fix was released in v0.3.3 and is already available from RubyGems.

Regards, Imanel