Cross::Talk
NOTA BENE:
This is not production ready, the basic functionality is there, but use in critical code is at your own risk.
Also, this thing is almost certainly going to give you performance problems of the most severe variety.
Support
Check CI for edge support, but ideally we support MRI > 1.9, (including 2.0), Reasonably recent RBX, and JRuby.
JRuby is broken right now though for unknown reasons.
Installation
Add this line to your application's Gemfile:
gem 'cross-talk'
And then execute:
$ bundle
Or install it yourself as:
$ gem install cross-talk
Usage
For any object (not just Celluloid Actors, though they'll work the best) simply
include Cross::Talk
and enjoy the following features for that class:
Any public method will automatically send out two events -- one at the beginning of execution, the other at the end. These are identified by the schema:
<class>#<method>:<time>
. Eg. for a classFoo
, and a methodbar
, callingFoo.new.bar
would send an eventFoo#bar:before
, and then aFoo#bar:after
. Note that the event is the same for any instance of the class, then read the "Plans" section, item 2.Any Cross::Talk class can bind to an event by using the
listen
macro at define-timeAny instance of a Cross::Talk class can bind to an event later, without forcing every other instance to also bind to that event. Think of the difference between
define_method
anddefine_singleton_method
(in fact they are implemented precisely that way)Celluloid Actors which include
Cross::Talk
will have the events sent to them asynchronously, so the event handler won't block while trying to dispatch those events
Plans
Improve the
listen
macro so you don't always need to supply an argument -- it should just be ignored if it's not there.Allow
listen
to bind to a specific instance of an event, rather than just the whole class of events.Refactor the codebase, it's a bit sprawling right now
Optimize for dispatch speed -- basically make it as lightweight as possible
Make the Event Dispatcher maybe use some thread primitives during dispatch around non-actors, so that we can join at the end and still send them asynchronous events?
Pipe dreams
Optionally back the event manager with a message queue, because why the hell not? It's worth a try, maybe it'll do something neat.
Experiment with making this usable efficiently over DCell. Including making the Event Manager run as a cluster of actors, notifying remote actors, etc.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request