cross-talk 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +6 -0
- data/Gemfile +11 -1
- data/NOTES.md +58 -0
- data/README.md +59 -4
- data/Rakefile +35 -1
- data/cross-talk.gemspec +2 -0
- data/lib/cross-talk.rb +14 -1
- data/lib/cross-talk/listener.rb +123 -0
- data/lib/cross-talk/manager.rb +38 -0
- data/lib/cross-talk/version.rb +1 -1
- data/spec/helpers/the.rb +17 -0
- data/spec/listener_spec.rb +102 -0
- data/spec/manager_spec.rb +76 -0
- data/spec/spec_helper.rb +32 -0
- metadata +38 -4
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/NOTES.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Cross::Talk -- Event Pub/Sub for PORC
|
2
|
+
|
3
|
+
## Design Notes
|
4
|
+
|
5
|
+
At require-time, create a `Cross::Talk::Manager` instance (a singleton). This
|
6
|
+
serves as the clearinghouse for all events. It is a celluloid actor.
|
7
|
+
|
8
|
+
NB. Though cross-talk is perfectly happy to run on MRI, you'll probably have
|
9
|
+
performance issues unless you run on RBX/JRuby, because we are likely sending
|
10
|
+
_lots_ of messages at any given point in time, and that means we're probably
|
11
|
+
eating a lot of CPU cycles.
|
12
|
+
|
13
|
+
Every public method call triggers and asynchronous notification to the
|
14
|
+
`Cross::Talk::Manager` (henceforth, `CTM`). Containing the method invoked, the
|
15
|
+
object that invoked it, and `:before` or `:after` (depending on which side of
|
16
|
+
the method you're on).
|
17
|
+
|
18
|
+
Another class can subscribe to any event by simply using the class macro
|
19
|
+
`#listen`, a la:
|
20
|
+
|
21
|
+
|
22
|
+
class Foo
|
23
|
+
include Celluloid::Actor
|
24
|
+
include Celluloid::Logger
|
25
|
+
include Cross::Talk
|
26
|
+
|
27
|
+
def bar
|
28
|
+
info "baz"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Listener
|
33
|
+
include Celluloid::Actor
|
34
|
+
include Celluloid::Logger
|
35
|
+
include Cross::Talk
|
36
|
+
|
37
|
+
listen Foo, :bar, :before do
|
38
|
+
info "before Foo#bar"
|
39
|
+
end
|
40
|
+
|
41
|
+
listen "Foo#bar:after" do |obj|
|
42
|
+
info "Calling terminate! on Foo instance"
|
43
|
+
obj.terminate!
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
Listener.new
|
49
|
+
Foo.new.bar
|
50
|
+
|
51
|
+
#=> before Foo#bar
|
52
|
+
#=> baz
|
53
|
+
#=> Calling terminate! on Foo instance
|
54
|
+
#=> <Celluloid::Actor Foo Terminated>
|
55
|
+
|
56
|
+
(mod output formatting).
|
57
|
+
|
58
|
+
|
data/README.md
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
-
# Cross::Talk
|
1
|
+
# Cross::Talk [](http://badge.fury.io/rb/cross-talk) [](http://travis-ci.org/jfredett/cross-talk) [](https://codeclimate.com/github/jfredett/cross-talk) [](https://coveralls.io/r/jfredett/cross-talk)
|
2
2
|
|
3
3
|
NOTA BENE:
|
4
4
|
|
5
|
-
This is
|
6
|
-
|
5
|
+
This is not production ready, the basic functionality is there, but use in
|
6
|
+
critical code is at your own risk.
|
7
|
+
|
8
|
+
Also, this thing is almost certainly going to give you performance problems of
|
9
|
+
the most severe variety.
|
10
|
+
|
11
|
+
## Support
|
12
|
+
|
13
|
+
Check CI for edge support, but ideally we support MRI > 1.9, (including 2.0),
|
14
|
+
Reasonably recent RBX, and JRuby.
|
15
|
+
|
16
|
+
JRuby is broken right now though for unknown reasons.
|
7
17
|
|
8
18
|
## Installation
|
9
19
|
|
@@ -21,7 +31,52 @@ Or install it yourself as:
|
|
21
31
|
|
22
32
|
## Usage
|
23
33
|
|
24
|
-
|
34
|
+
For any object (not just Celluloid Actors, though they'll work the best) simply
|
35
|
+
include `Cross::Talk` and enjoy the following features for that class:
|
36
|
+
|
37
|
+
1. Any public method will automatically send out two events -- one at the
|
38
|
+
beginning of execution, the other at the end. These are identified by the
|
39
|
+
schema: `<class>#<method>:<time>`. Eg. for a class `Foo`, and a method `bar`,
|
40
|
+
calling `Foo.new.bar` would send an event `Foo#bar:before`, and then a
|
41
|
+
`Foo#bar:after`. Note that the event is the same for any instance of the
|
42
|
+
class, then read the "Plans" section, item 2.
|
43
|
+
|
44
|
+
2. Any Cross::Talk class can bind to an event by using the `listen` macro at
|
45
|
+
define-time
|
46
|
+
|
47
|
+
3. Any instance of a Cross::Talk class can bind to an event later, without
|
48
|
+
forcing every other instance to also bind to that event. Think of the
|
49
|
+
difference between `define_method` and `define_singleton_method` (in fact
|
50
|
+
they are implemented precisely that way)
|
51
|
+
|
52
|
+
4. Celluloid Actors which include `Cross::Talk` will have the events sent to
|
53
|
+
them asynchronously, so the event handler won't block while trying to
|
54
|
+
dispatch those events
|
55
|
+
|
56
|
+
|
57
|
+
## Plans
|
58
|
+
|
59
|
+
1. Improve the `listen` macro so you don't always need to supply an argument --
|
60
|
+
it should just be ignored if it's not there.
|
61
|
+
|
62
|
+
2. Allow `listen` to bind to a specific _instance_ of an event, rather than just
|
63
|
+
the whole class of events.
|
64
|
+
|
65
|
+
3. Refactor the codebase, it's a bit sprawling right now
|
66
|
+
|
67
|
+
4. Optimize for dispatch speed -- basically make it as lightweight as possible
|
68
|
+
|
69
|
+
5. Make the Event Dispatcher maybe use some thread primitives during dispatch
|
70
|
+
around non-actors, so that we can join at the end and still send them
|
71
|
+
asynchronous events?
|
72
|
+
|
73
|
+
### Pipe dreams
|
74
|
+
|
75
|
+
1. Optionally back the event manager with a message queue, because why the hell
|
76
|
+
not? It's worth a try, maybe it'll do something neat.
|
77
|
+
|
78
|
+
2. Experiment with making this usable efficiently over DCell. Including making
|
79
|
+
the Event Manager run as a cluster of actors, notifying remote actors, etc.
|
25
80
|
|
26
81
|
## Contributing
|
27
82
|
|
data/Rakefile
CHANGED
@@ -1 +1,35 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc 'run specs'
|
7
|
+
RSpec::Core::RakeTask.new do |task|
|
8
|
+
task.rspec_opts = ["-c", "-f progress"]
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => :spec
|
12
|
+
|
13
|
+
|
14
|
+
task :flog do
|
15
|
+
puts "#### FLOG ####"
|
16
|
+
system 'flog lib/*'
|
17
|
+
puts "##############"
|
18
|
+
end
|
19
|
+
|
20
|
+
task :flay do
|
21
|
+
puts "#### FLAY ####"
|
22
|
+
system 'flay lib/*'
|
23
|
+
puts "##############"
|
24
|
+
end
|
25
|
+
|
26
|
+
task :mutant, [:klass] do |_, args|
|
27
|
+
puts "#### MUTANT TESTING ####"
|
28
|
+
system "mutant -I lib -r cross-talk --rspec-full #{args[:name] || '::Katuv'}"
|
29
|
+
puts "########################"
|
30
|
+
end
|
31
|
+
|
32
|
+
task :metrics => [:flog, :flay]
|
33
|
+
|
34
|
+
|
35
|
+
task :all => [:spec, :mutant, :metrics]
|
data/cross-talk.gemspec
CHANGED
data/lib/cross-talk.rb
CHANGED
@@ -1,7 +1,20 @@
|
|
1
|
+
require 'celluloid'
|
2
|
+
|
1
3
|
require "cross-talk/version"
|
4
|
+
require 'cross-talk/manager'
|
5
|
+
require 'cross-talk/listener'
|
2
6
|
|
3
7
|
module Cross
|
4
8
|
module Talk
|
5
|
-
#
|
9
|
+
# Access the Event Manager
|
10
|
+
def self.manager
|
11
|
+
Celluloid::Actor[:manager] ||= Cross::Talk::Manager.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included(base)
|
15
|
+
base.send(:include, Listener)
|
16
|
+
end
|
6
17
|
end
|
7
18
|
end
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Cross
|
2
|
+
module Talk
|
3
|
+
module Listener
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.send(:extend, ClassMethods)
|
7
|
+
base.send(:include, Celluloid::Logger)
|
8
|
+
base.send(:extend, Celluloid::Logger)
|
9
|
+
|
10
|
+
# This makes sure that when we add a new hook at runtime, we rebuild all
|
11
|
+
# of our hooks so that they're up-to-date.
|
12
|
+
base.instance_eval do
|
13
|
+
listen base, :__new_hook, :before do
|
14
|
+
register_hooks!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def register_hooks!
|
21
|
+
self.class.registration_hooks.each { |hook| hook.call(__get_receiver) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(*_)
|
25
|
+
register_hooks!
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
def silenced?
|
30
|
+
@__silenced
|
31
|
+
end
|
32
|
+
|
33
|
+
def silence!
|
34
|
+
@__silenced = true
|
35
|
+
end
|
36
|
+
|
37
|
+
def unsilence!
|
38
|
+
@__silenced = false
|
39
|
+
end
|
40
|
+
|
41
|
+
def silently(&block)
|
42
|
+
silence!
|
43
|
+
block.call
|
44
|
+
unsilence!
|
45
|
+
end
|
46
|
+
|
47
|
+
def listen(klass, event, timing, &block)
|
48
|
+
event_name = "#{klass}##{event}:#{timing}"
|
49
|
+
Cross::Talk.manager.notify('__new_hook:before', event_name)
|
50
|
+
define_singleton_method event_name, &block
|
51
|
+
Cross::Talk.manager.register(event_name, __get_receiver)
|
52
|
+
Cross::Talk.manager.notify('__new_hook:after', event_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def __notify_event(method, timing)
|
58
|
+
return if Object.methods.include?(method)
|
59
|
+
return unless public_methods(false).include?(method)
|
60
|
+
return if silenced?
|
61
|
+
|
62
|
+
receiver = __get_receiver
|
63
|
+
event_name = "#{receiver.class}##{method}:#{timing}"
|
64
|
+
|
65
|
+
Cross::Talk.manager.notify(event_name, receiver)
|
66
|
+
end
|
67
|
+
|
68
|
+
def __get_receiver
|
69
|
+
return Celluloid::Actor.current if is_a?(Celluloid)
|
70
|
+
return self
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module ClassMethods
|
75
|
+
def registration_hooks
|
76
|
+
@registration_hooks ||= []
|
77
|
+
end
|
78
|
+
|
79
|
+
def listen(klass, event, timing, &block)
|
80
|
+
event_name = "#{klass}##{event}:#{timing}"
|
81
|
+
Cross::Talk.manager.notify('__new_hook:before', event_name)
|
82
|
+
define_hook! event_name, &block
|
83
|
+
registration_hooks << proc { |actor| Cross::Talk.manager.register(event_name, actor) }
|
84
|
+
Cross::Talk.manager.notify('__new_hook:after', event_name)
|
85
|
+
end
|
86
|
+
|
87
|
+
def notify(method_name)
|
88
|
+
class_eval %{
|
89
|
+
alias __old_#{method_name} #{method_name}
|
90
|
+
|
91
|
+
def #{method_name}(*args, &block)
|
92
|
+
__notify_event(#{method_name.inspect}, :before)
|
93
|
+
result = __old_#{method_name}(*args, &block)
|
94
|
+
__notify_event(#{method_name.inspect}, :after)
|
95
|
+
result
|
96
|
+
end
|
97
|
+
}
|
98
|
+
|
99
|
+
send(:private, method_name) if private_instance_methods.include?("__old_#{method_name}".to_sym)
|
100
|
+
send(:protected, method_name) if protected_instance_methods.include?("__old_#{method_name}".to_sym)
|
101
|
+
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def method_added(method)
|
106
|
+
# if we're redefining a method, the lock is set to true, so bug out.
|
107
|
+
return if @lock
|
108
|
+
#don't notify hook methods
|
109
|
+
return if method =~ /^.*#.*:.*$/
|
110
|
+
# don't notify pseudoprivate methods
|
111
|
+
return if method =~ /^__/
|
112
|
+
@lock = true
|
113
|
+
notify(method)
|
114
|
+
@lock = false
|
115
|
+
end
|
116
|
+
|
117
|
+
def define_hook!(method, &block)
|
118
|
+
define_method(method, &block)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Cross
|
2
|
+
module Talk
|
3
|
+
class Manager
|
4
|
+
include Celluloid
|
5
|
+
include Celluloid::Logger
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@event_table = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def notify(event, sender)
|
12
|
+
receivers_for(event).each do |receiver|
|
13
|
+
next unless receiver.respond_to?(event)
|
14
|
+
if receiver.respond_to?(:async)
|
15
|
+
receiver.async
|
16
|
+
else
|
17
|
+
receiver
|
18
|
+
end.send(event, sender)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def register(event, receiver)
|
23
|
+
receivers_for(event) << receiver
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :event_table
|
30
|
+
|
31
|
+
def receivers_for(event)
|
32
|
+
# We need to ||= here to avoid a weird behavior with Hash.new { [] } --
|
33
|
+
# you can't destructively update the first element to it.
|
34
|
+
event_table[event] ||= Set.new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/cross-talk/version.rb
CHANGED
data/spec/helpers/the.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Cross
|
3
|
+
module Talk
|
4
|
+
module DSL
|
5
|
+
module Macros
|
6
|
+
def the(sym, &block)
|
7
|
+
context sym do
|
8
|
+
subject { if sym.is_a? Class then sym else send sym end }
|
9
|
+
it &block
|
10
|
+
end
|
11
|
+
end
|
12
|
+
alias the_class the
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe Cross::Talk::Listener do
|
5
|
+
before :all do
|
6
|
+
class Sender
|
7
|
+
include Celluloid
|
8
|
+
include Cross::Talk
|
9
|
+
|
10
|
+
def test
|
11
|
+
end
|
12
|
+
|
13
|
+
def late
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def protected_method
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def private_method
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Receiver
|
28
|
+
include Celluloid
|
29
|
+
include Cross::Talk
|
30
|
+
|
31
|
+
listen Sender, :test, :after do |sender|
|
32
|
+
@notified = true
|
33
|
+
end
|
34
|
+
|
35
|
+
listen Sender, :private_method, :after do |sender|
|
36
|
+
debug "Should never occur"
|
37
|
+
@notified = true
|
38
|
+
end
|
39
|
+
|
40
|
+
listen Sender, :protected_method, :after do |sender|
|
41
|
+
debug "Should never occur"
|
42
|
+
@notified = true
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_been_notified?
|
46
|
+
@notified
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
after :all do
|
51
|
+
Object.send(:remove_const, :Receiver)
|
52
|
+
Object.send(:remove_const, :Sender)
|
53
|
+
end
|
54
|
+
|
55
|
+
let!(:receiver) { Receiver.new }
|
56
|
+
let!(:other_receiver) { Receiver.new }
|
57
|
+
let!(:sender) { Sender.new }
|
58
|
+
|
59
|
+
subject { receiver }
|
60
|
+
|
61
|
+
context 'late-bound listen' do
|
62
|
+
|
63
|
+
before do
|
64
|
+
receiver.listen(Sender, :late, :after) do |*_|
|
65
|
+
@notified = true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
the(:receiver) { should_not have_been_notified }
|
70
|
+
the(:other_receiver) { should_not have_been_notified }
|
71
|
+
|
72
|
+
describe 'when the message is sent' do
|
73
|
+
before { sender.late }
|
74
|
+
|
75
|
+
the(:receiver) { should have_been_notified }
|
76
|
+
the(:other_receiver) { should_not have_been_notified }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'define-time bound listen' do
|
81
|
+
it { should respond_to :"Sender#test:after" }
|
82
|
+
it { should_not have_been_notified }
|
83
|
+
|
84
|
+
describe 'calling the method' do
|
85
|
+
before { sender.test }
|
86
|
+
|
87
|
+
it { should have_been_notified }
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'calling a private method on the sender' do
|
91
|
+
before { sender.send(:private_method) }
|
92
|
+
|
93
|
+
it { should_not have_been_notified }
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'calling a protected method on the sender' do
|
97
|
+
before { sender.send(:protected_method) }
|
98
|
+
|
99
|
+
it { should_not have_been_notified }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe Cross::Talk::Manager do
|
5
|
+
subject(:manager) { Cross::Talk.manager }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
class Receiver
|
9
|
+
include Celluloid
|
10
|
+
include Celluloid::Logger
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
Cross::Talk.manager.register('an_event', Actor.current)
|
14
|
+
end
|
15
|
+
|
16
|
+
def an_event(*_)
|
17
|
+
@notification = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_received_notification?
|
21
|
+
@notification
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class StupidReceiver
|
26
|
+
include Celluloid
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
Cross::Talk.manager.register('an_event', Actor.current)
|
30
|
+
end
|
31
|
+
|
32
|
+
# I'm dumb because I didn't implement the event method!
|
33
|
+
end
|
34
|
+
|
35
|
+
class NonReceiver
|
36
|
+
include Celluloid
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
Cross::Talk.manager.register('another_event', Actor.current)
|
40
|
+
end
|
41
|
+
|
42
|
+
def another_event(*_)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
after :all do
|
48
|
+
Object.send(:remove_const, :Receiver)
|
49
|
+
Object.send(:remove_const, :NonReceiver)
|
50
|
+
Object.send(:remove_const, :StupidReceiver)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
describe 'api' do
|
55
|
+
it { should respond_to :notify }
|
56
|
+
it { should respond_to :register }
|
57
|
+
end
|
58
|
+
|
59
|
+
let!(:receiver) { Receiver.new }
|
60
|
+
let!(:non_receiver) { NonReceiver.new }
|
61
|
+
let!(:stupid_receiver) { StupidReceiver.new }
|
62
|
+
|
63
|
+
before { manager.notify('an_event', nil) }
|
64
|
+
|
65
|
+
it 'notifies registered receivers when an event occurs' do
|
66
|
+
receiver.should have_received_notification
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'only notifies registered receivers which actually define the event method' do
|
70
|
+
stupid_receiver.should_not have_received :an_event
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'does not notify receivers of other messages of that message' do
|
74
|
+
non_receiver.should_not have_received :an_event
|
75
|
+
end
|
76
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
require 'cross-talk'
|
6
|
+
|
7
|
+
require 'rspec-spies'
|
8
|
+
|
9
|
+
require 'coveralls'
|
10
|
+
Coveralls.wear!
|
11
|
+
|
12
|
+
#include helpers
|
13
|
+
Dir["./spec/helpers/*.rb"].each { |file| require file }
|
14
|
+
|
15
|
+
#include shared examples
|
16
|
+
Dir["./spec/shared/*_examples.rb"].each { |file| require file }
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.before do
|
20
|
+
allow_message_expectations_on_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
24
|
+
|
25
|
+
config.extend(RSpec::Cross::Talk::DSL::Macros)
|
26
|
+
end
|
27
|
+
|
28
|
+
class RSpec::Mocks::Mock
|
29
|
+
def inspect
|
30
|
+
"double(#{@name.inspect})"
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cross-talk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
13
|
-
dependencies:
|
12
|
+
date: 2013-04-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: celluloid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
description: A Pub/Sub Event Management Service for Ruby Classes
|
15
31
|
email:
|
16
32
|
- jfredett@gmail.com
|
@@ -19,13 +35,21 @@ extensions: []
|
|
19
35
|
extra_rdoc_files: []
|
20
36
|
files:
|
21
37
|
- .gitignore
|
38
|
+
- .travis.yml
|
22
39
|
- Gemfile
|
23
40
|
- LICENSE.txt
|
41
|
+
- NOTES.md
|
24
42
|
- README.md
|
25
43
|
- Rakefile
|
26
44
|
- cross-talk.gemspec
|
27
45
|
- lib/cross-talk.rb
|
46
|
+
- lib/cross-talk/listener.rb
|
47
|
+
- lib/cross-talk/manager.rb
|
28
48
|
- lib/cross-talk/version.rb
|
49
|
+
- spec/helpers/the.rb
|
50
|
+
- spec/listener_spec.rb
|
51
|
+
- spec/manager_spec.rb
|
52
|
+
- spec/spec_helper.rb
|
29
53
|
homepage: ''
|
30
54
|
licenses: []
|
31
55
|
post_install_message:
|
@@ -38,16 +62,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
38
62
|
- - ! '>='
|
39
63
|
- !ruby/object:Gem::Version
|
40
64
|
version: '0'
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
hash: 635870557992844421
|
41
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
69
|
none: false
|
43
70
|
requirements:
|
44
71
|
- - ! '>='
|
45
72
|
- !ruby/object:Gem::Version
|
46
73
|
version: '0'
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
hash: 635870557992844421
|
47
77
|
requirements: []
|
48
78
|
rubyforge_project:
|
49
79
|
rubygems_version: 1.8.24
|
50
80
|
signing_key:
|
51
81
|
specification_version: 3
|
52
82
|
summary: A Pub/Sub Event Management Service for Ruby Classes
|
53
|
-
test_files:
|
83
|
+
test_files:
|
84
|
+
- spec/helpers/the.rb
|
85
|
+
- spec/listener_spec.rb
|
86
|
+
- spec/manager_spec.rb
|
87
|
+
- spec/spec_helper.rb
|