Chuck Remes
2008-Feb-13 09:36 UTC
[Eventmachine-talk] eventable experiment and application-level
While searching through some old threads on this list, I ran across some discussions from May 2006 regarding the addition of application- level events via a new class called Eventable. I took a look through the svn repository and saw the core-model-1 through core-model-3 experiments, but it doesn''t looks like any of this code ever made it to trunk. Is there still a plan to allow posting and receiving internally- defined events or is EM sticking with only processing IO events? cr
James Tucker
2008-Feb-13 12:40 UTC
[Eventmachine-talk] eventable experiment and application-level
I took a look at Eventable when I needed internal event processing, or at least, a centralized ''listen for event'' system. It''s possible to do this all kinds of ways, I simply use a hash with some syntax sugar tacked on. I didn''t use Eventable if i remember correctly, because: a) I had no idea if it was being used somewhere else b) the implementation is either missing or outside of ruby? c) There is no way to remove event handlers d) Some of our handlers for some apps are growing to resemble something that plays a logical part not too far detached from a ''controller'' from an MVC stack. So I defined everything ruby side, using as I say, a hash plus some syntax sugar. For the implementations with fatter handlers (something larger than a proc or Method to call), I also provided a mechanism for auto- discovering the handlers. (At this point, it really does start to resemble controllers). A simple starter: Handlers = Hash.new { |h,k| h[k] = [] } class <<Handlers def handle(name, *args) self[name].each do |h| begin h.call *args rescue end end end end Handlers[:my_event] << proc { puts "my event occurred" } Handlers.handle(:my_event) pr = proc { |arg| puts "event2: #{arg}" } Handlers[:my_event2] << pr Handlers.handle(:my_event2, ''test'') Handlers[:my_event].delete(pr) :"salt to taste." (I knocked that out in the mail, so if there''s a mistake please feel free to ask, it should just work in irb) Monkey patch your handler collection (the array in hash.new) for syntax like Handlers[:my_event].fire(*args), should you so desire. You can use any old objects for indexes, and anything that implements ''call'' as a callback on the event (procs, methods, etc). It''s possibly worth noting that there''s no EventMachine code in there. You can easily wrap this up in deferrables and defer calls, make event processing queues, wrap short jobs in simple timer stacks for ''lightly deferred'' scheduling, etc. Keeping it real simple helps a lot. I explicitly catch stuff in the handlers, when processing the list; you often don''t want to leave exceptions that raise up the stack, and it''s even worse in a defer or timer, or some place without an errback (i.e. where the exception would hit the EM reactor core). On 13 Feb 2008, at 17:36, Chuck Remes wrote:> While searching through some old threads on this list, I ran across > some discussions from May 2006 regarding the addition of application- > level events via a new class called Eventable. I took a look through > the svn repository and saw the core-model-1 through core-model-3 > experiments, but it doesn''t looks like any of this code ever made it > to trunk. > > Is there still a plan to allow posting and receiving internally- > defined events or is EM sticking with only processing IO events? > > cr > > _______________________________________________ > Eventmachine-talk mailing list > Eventmachine-talk at rubyforge.org > http://rubyforge.org/mailman/listinfo/eventmachine-talk
Tony Arcieri
2008-Feb-13 13:17 UTC
[Eventmachine-talk] eventable experiment and application-level
On Feb 13, 2008 1:40 PM, James Tucker <jftucker at gmail.com> wrote:> I took a look at Eventable when I needed internal event processing, or > at least, a centralized ''listen for event'' system. > > It''s possible to do this all kinds of ways, I simply use a hash with > some syntax sugar tacked on. > > I didn''t use Eventable if i remember correctly, because: > > a) I had no idea if it was being used somewhere else > b) the implementation is either missing or outside of ruby? > c) There is no way to remove event handlers > d) Some of our handlers for some apps are growing to resemble > something that plays a logical part not too far detached from a > ''controller'' from an MVC stack. > > So I defined everything ruby side, using as I say, a hash plus some > syntax sugar. > > For the implementations with fatter handlers (something larger than a > proc or Method to call), I also provided a mechanism for auto- > discovering the handlers. (At this point, it really does start to > resemble controllers). > > A simple starter: > > > Handlers = Hash.new { |h,k| h[k] = [] } > > class <<Handlers > def handle(name, *args) > self[name].each do |h| > begin > h.call *args > rescue > end > end > end > end > > Handlers[:my_event] << proc { puts "my event occurred" } > > Handlers.handle(:my_event) > > pr = proc { |arg| puts "event2: #{arg}" } > Handlers[:my_event2] << pr > > Handlers.handle(:my_event2, ''test'') > Handlers[:my_event].delete(pr) > > :"salt to taste." >That''s starting to look an awful lot like the Tasks / Channels approach to concurrency in Rubinius, except asynchronous. -- Tony Arcieri ClickCaster, Inc. tony at clickcaster.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/eventmachine-talk/attachments/20080213/f0d78146/attachment.html
Chuck Remes
2008-Feb-13 14:02 UTC
[Eventmachine-talk] eventable experiment and application-level
On Feb 13, 2008, at 2:40 PM, James Tucker wrote:> I took a look at Eventable when I needed internal event processing, or > at least, a centralized ''listen for event'' system. > > It''s possible to do this all kinds of ways, I simply use a hash with > some syntax sugar tacked on. > > I didn''t use Eventable if i remember correctly, because: > > a) I had no idea if it was being used somewhere else > b) the implementation is either missing or outside of ruby? > c) There is no way to remove event handlers > d) Some of our handlers for some apps are growing to resemble > something that plays a logical part not too far detached from a > ''controller'' from an MVC stack. > > So I defined everything ruby side, using as I say, a hash plus some > syntax sugar. > > For the implementations with fatter handlers (something larger than a > proc or Method to call), I also provided a mechanism for auto- > discovering the handlers. (At this point, it really does start to > resemble controllers). > > A simple starter: > > > Handlers = Hash.new { |h,k| h[k] = [] } > > class <<Handlers > def handle(name, *args) > self[name].each do |h| > begin > h.call *args > rescue > end > end > end > end > > Handlers[:my_event] << proc { puts "my event occurred" } > > Handlers.handle(:my_event) > > pr = proc { |arg| puts "event2: #{arg}" } > Handlers[:my_event2] << pr > > Handlers.handle(:my_event2, ''test'') > Handlers[:my_event].delete(pr) > > :"salt to taste." > > (I knocked that out in the mail, so if there''s a mistake please feel > free to ask, it should just work in irb)That looks pretty reasonable. I can use that as a guideline. Thanks!> [snip] > > It''s possibly worth noting that there''s no EventMachine code in there. > You can easily wrap this up in deferrables and defer calls, make event > processing queues, wrap short jobs in simple timer stacks for ''lightly > deferred'' scheduling, etc. Keeping it real simple helps a lot.This is the rub right here. If I set a timer task to run very frequently, if there is no work to perform then this essentially devolves into polling. If I run the timer task once per second, pending events could wait a "long" time before being processed; throughput would suck. I want to be able to post events to the reactor core and have it handle the dispatching for me. What would you recommend? If I''m missing something obvious or already answered, no need to be gentle. :-) cr
James Tucker
2008-Feb-13 23:09 UTC
[Eventmachine-talk] eventable experiment and application-level
On 13 Feb 2008, at 22:02, Chuck Remes wrote:> > > That looks pretty reasonable. I can use that as a guideline. Thanks!welcome.> > >> [snip] >> >> It''s possibly worth noting that there''s no EventMachine code in >> there. >> You can easily wrap this up in deferrables and defer calls, make >> event >> processing queues, wrap short jobs in simple timer stacks for >> ''lightly >> deferred'' scheduling, etc. Keeping it real simple helps a lot. > > This is the rub right here. If I set a timer task to run very > frequently, if there is no work to perform then this essentially > devolves into polling. If I run the timer task once per second, > pending events could wait a "long" time before being processed; > throughput would suck.Well if your desire was for a defer, then you could create a new one any time a request comes in and there isn''t one running. If there is, you can populate a queue (although, a non-blocking one, rather than ruby''s thread Queue). I''ll be testing this structure with some DB drivers soon.> I want to be able to post events to the reactor core and have it > handle the dispatching for me. What would you recommend? If I''m > missing something obvious or already answered, no need to be > gentle. :-)Well, passing it to the reactor loop is / would be essentially identical to doing this: Handlers[:event_name].each do |h| ::EventMachine::add_timer(0, &h) end Only you wouldn''t really want to spam the timer map. Incidentally, apart from that spam, it''s quite similar to doing all of them in a single timer (invert the two blocks, basically). As I said when I said keep it simple, start with the naive implementation, no threads (defer), no deferrables, etc. Optimize if you find you need to (mostly, you should not). Defer for example, is unlikely to increase total performance significantly, unless the contents of the call are going out to a high latency external interface (like a blocking call, to say, a database). Yes, it does start to resemble polling, only that''s exactly why the drive for maintaining simplicity. In fact, the best way to optimize in some of these situations, is to implement two applications, and have one do nothing but take over high latency jobs. The low latency ''client facing'' app is then free to continue processing client requests, maybe whilst waiting on deferrable that close on responses from the high latency app. Other useful features can then be added under this idea, like coalescing messages, which can be used to rapidly overcome the extra overhead added (again, for some or a lot of cases).> > > cr > _______________________________________________ > Eventmachine-talk mailing list > Eventmachine-talk at rubyforge.org > http://rubyforge.org/mailman/listinfo/eventmachine-talk
James Tucker
2008-Feb-13 23:09 UTC
[Eventmachine-talk] eventable experiment and application-level
On 13 Feb 2008, at 21:17, Tony Arcieri wrote:> > That''s starting to look an awful lot like the Tasks / Channels > approach to concurrency in Rubinius, except asynchronous.I knew I was looking forward to those, and I haven''t even looked at the implementation yet.> > > -- > Tony Arcieri > ClickCaster, Inc. > tony at clickcaster.com _______________________________________________ > Eventmachine-talk mailing list > Eventmachine-talk at rubyforge.org > http://rubyforge.org/mailman/listinfo/eventmachine-talk-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/eventmachine-talk/attachments/20080214/51bc5e3d/attachment.html