Вопрос

I've heard that all I/O should be called from the Main Thread, not from any other Threads (defers). Can somebody explain why that is so?

I never read anything about that in the documentation. The EventMachine screencasts from PeepCode mention this, as well as this screencast: http://confreaks.com/videos/555-scotlandruy2011-introduction-to-eventmachine-and-evented-programming (both without explanation though)

Это было полезно?

Решение

EM was written to circumvent thread-safety issues by running all operations in the reactor thread.

EM.defer (any Tread.new really) breaks away from this design principle by switching some part of code execution away from the main thread (the reactor), but you're still supposed to interact with the reactor only through errback and callback blocks which are executed in reactor, not the code block which is executed in a separate thread (for Thread.new people use EM.next_tick for same effect).

Shorter explanation is, EM isn't thread-safe :) That's why you shouldn't call EM stuff from other threads (you need to be able to handle synchronization if you do).

EM docs say as much without saying as much they say:

Yes but if you do EM::connect from a different thread, then it may throw unbound errors. To avoid this put your EM::connect stuffs in a next_tick call.

...and unbound errors are just the most probable result (I've seen everything from blocks, nils, non-execution without exceptions, ...), any number of nasty thread unsafety issues are bound to happen if you presume you can interact with the reactor thoughtlessly, https://github.com/eventmachine/eventmachine/wiki/FAQ#does-em-work-with-other-ruby-threads-running

And a piece of advice, look into celluloid, EM seems to not be maintained any more

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top