reactor 0.4.0 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -4
- data/lib/reactor/event.rb +36 -41
- data/lib/reactor/version.rb +1 -1
- data/reactor.gemspec +2 -0
- data/spec/event_spec.rb +22 -5
- data/spec/models/concerns/subscribable_spec.rb +3 -2
- data/spec/models/subscriber_spec.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e9a74358c1037c16f0a343f02b5840c77607569
|
4
|
+
data.tar.gz: f8ba2b02d95b0934af0d57add8b75c33c2bf49b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fae79f206e0011b096b6817c0dcf3dde568fed64329b22d2708549dc12725003bcc1ce64537ec255ecc7d6437fddf59b50afe295fa66a801f596712785cc9e88
|
7
|
+
data.tar.gz: c450f5814c17cf71e6ba9f2f92a7d41dad867ba542433d4062f5ca9492b7a00e89abb6800db9980896531eeac6873a9122c0c9061cad6021af0855f8abe90969
|
data/Gemfile
CHANGED
data/lib/reactor/event.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class Reactor::Event
|
2
2
|
include Reactor::OptionallySubclassable
|
3
|
+
include Sidekiq::Worker
|
3
4
|
|
4
5
|
attr_accessor :data
|
5
6
|
|
@@ -10,6 +11,30 @@ class Reactor::Event
|
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
14
|
+
def perform(name, data)
|
15
|
+
data.merge!(fired_at: Time.current)
|
16
|
+
Reactor::Subscriber.where(event: name).each do |subscriber|
|
17
|
+
Reactor::Subscriber.delay.fire subscriber.id, data
|
18
|
+
end
|
19
|
+
|
20
|
+
#TODO: support more matching?
|
21
|
+
Reactor::Subscriber.where(event: '*').each do |s|
|
22
|
+
Reactor::Subscriber.delay.fire s.id, data
|
23
|
+
end
|
24
|
+
|
25
|
+
if (static_subscribers = Reactor::SUBSCRIBERS[name] || []).any?
|
26
|
+
static_subscribers.each do |callback|
|
27
|
+
delay = callback[:options].try(:[], :delay) || 0
|
28
|
+
case method = callback[:method]
|
29
|
+
when Symbol
|
30
|
+
callback[:source].delay_for(delay).send method, Reactor::Event.new(data.merge(event: name))
|
31
|
+
else
|
32
|
+
method.call Reactor::Event.new(data.merge(event: name))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
13
38
|
def method_missing(method, *args)
|
14
39
|
if method.to_s.include?('=')
|
15
40
|
try_setter(method, *args)
|
@@ -23,58 +48,28 @@ class Reactor::Event
|
|
23
48
|
end
|
24
49
|
|
25
50
|
class << self
|
51
|
+
def perform(name, data)
|
52
|
+
new.perform(name, data)
|
53
|
+
end
|
54
|
+
|
26
55
|
def publish(name, data = {})
|
27
56
|
message = new(data.merge(event: name))
|
28
57
|
|
29
58
|
if message.at.nil?
|
30
|
-
|
59
|
+
perform_async name, message.data
|
31
60
|
elsif message.at.future?
|
32
|
-
|
61
|
+
perform_at message.at, name, message.data
|
33
62
|
end
|
34
63
|
end
|
35
64
|
|
36
65
|
def reschedule(name, data = {})
|
66
|
+
scheduled_jobs = Sidekiq::ScheduledSet.new
|
37
67
|
job = scheduled_jobs.detect do |job|
|
38
|
-
job['
|
39
|
-
|
40
|
-
remove_scheduled_job job if job
|
41
|
-
delay.publish(name, data.except(:was)) if data[:at].future?
|
42
|
-
end
|
43
|
-
|
44
|
-
def process(name, data)
|
45
|
-
data.merge!(fired_at: Time.current)
|
46
|
-
Reactor::Subscriber.where(event: name.to_s).each do |subscriber|
|
47
|
-
Reactor::Subscriber.delay.fire subscriber.id, data
|
48
|
-
end
|
49
|
-
|
50
|
-
#TODO: support more matching?
|
51
|
-
Reactor::Subscriber.where(event: '*').each do |s|
|
52
|
-
Reactor::Subscriber.delay.fire s.id, data
|
53
|
-
end
|
54
|
-
|
55
|
-
if (static_subscribers = Reactor::SUBSCRIBERS[name.to_s] || []).any?
|
56
|
-
static_subscribers.each do |callback|
|
57
|
-
delay = callback[:options].try(:[], :delay) || 0
|
58
|
-
case method = callback[:method]
|
59
|
-
when Symbol
|
60
|
-
callback[:source].delay_for(delay).send method, Reactor::Event.new(data.merge(event: name.to_s))
|
61
|
-
else
|
62
|
-
method.call Reactor::Event.new(data.merge(event: name.to_s))
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def scheduled_jobs(options = {})
|
69
|
-
Sidekiq.redis do |r|
|
70
|
-
from = options[:from] ? options[:from].to_f.to_s : '-inf'
|
71
|
-
to = options[:to] ? options[:to].to_f.to_s : '+inf'
|
72
|
-
r.zrangebyscore('schedule', from, to).map{|job| MultiJson.decode(job)}
|
68
|
+
job['args'].first == name.to_s &&
|
69
|
+
job.score == data[:was].to_f
|
73
70
|
end
|
74
|
-
|
75
|
-
|
76
|
-
def remove_scheduled_job(job)
|
77
|
-
Sidekiq.redis { |r| r.zrem 'schedule', MultiJson.encode(job) }
|
71
|
+
job.delete
|
72
|
+
publish(name, data.except(:was)) if data[:at].future?
|
78
73
|
end
|
79
74
|
end
|
80
75
|
|
data/lib/reactor/version.rb
CHANGED
data/reactor.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency "sidekiq", ">= 2.13.0"
|
22
|
+
spec.add_dependency 'activerecord', '3.2.13'
|
21
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
24
|
spec.add_development_dependency "rake"
|
23
25
|
spec.add_development_dependency "rspec"
|
data/spec/event_spec.rb
CHANGED
@@ -17,23 +17,40 @@ describe Reactor::Event do
|
|
17
17
|
let(:event_name) { :user_did_this }
|
18
18
|
|
19
19
|
describe 'publish' do
|
20
|
-
it 'fires the first
|
21
|
-
Reactor::Event.should_receive(:
|
20
|
+
it 'fires the first perform and sets message event_id' do
|
21
|
+
Reactor::Event.should_receive(:perform_async).with(event_name, 'actor_id' => '1', 'event' => :user_did_this)
|
22
22
|
Reactor::Event.publish(:user_did_this, actor_id: '1')
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
describe '
|
26
|
+
describe 'perform' do
|
27
27
|
before { Reactor::Subscriber.create(event: :user_did_this) }
|
28
28
|
after { Reactor::Subscriber.destroy_all }
|
29
29
|
it 'fires all subscribers' do
|
30
30
|
Reactor::Subscriber.any_instance.should_receive(:fire).with(hash_including(actor_id: '1'))
|
31
|
-
Reactor::Event.
|
31
|
+
Reactor::Event.perform(event_name, actor_id: '1')
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'sets a fired_at key in event data' do
|
35
35
|
Reactor::Subscriber.any_instance.should_receive(:fire).with(hash_including(fired_at: anything))
|
36
|
-
Reactor::Event.
|
36
|
+
Reactor::Event.perform(event_name, actor_id: '1')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'reschedule', :sidekiq do
|
41
|
+
let(:scheduled) { Sidekiq::ScheduledSet.new }
|
42
|
+
let(:time) { 1.hour.from_now }
|
43
|
+
|
44
|
+
it 'can schedule and reschedule an event in the future' do
|
45
|
+
expect {
|
46
|
+
jid = Reactor::Event.publish :turtle_time, at: time
|
47
|
+
scheduled.find_job(jid).score.should == time.to_f
|
48
|
+
}.to change { scheduled.size }.by(1)
|
49
|
+
|
50
|
+
expect {
|
51
|
+
jid = Reactor::Event.reschedule :turtle_time, at: (time + 2.hours), was: time
|
52
|
+
scheduled.find_job(jid).score.should == (time + 2.hours).to_f
|
53
|
+
}.to_not change { scheduled.size }
|
37
54
|
end
|
38
55
|
end
|
39
56
|
|
@@ -16,6 +16,7 @@ class Auction < ActiveRecord::Base
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe Reactor::Subscribable do
|
19
|
+
let(:scheduled) { Sidekiq::ScheduledSet.new }
|
19
20
|
|
20
21
|
describe 'on_event' do
|
21
22
|
it 'binds block of code statically to event being fired' do
|
@@ -30,8 +31,8 @@ describe Reactor::Subscribable do
|
|
30
31
|
end
|
31
32
|
|
32
33
|
it 'can be delayed', :sidekiq do
|
33
|
-
Reactor::Event.
|
34
|
-
job =
|
34
|
+
Reactor::Event.perform('pooped', {})
|
35
|
+
job = scheduled.detect{|job| job.score > 4.minutes.from_now.to_f && job.score <= 5.minutes.from_now.to_f }
|
35
36
|
job.should be_present
|
36
37
|
job['args'].last.should include("pick_up_poop")
|
37
38
|
end
|
@@ -27,7 +27,7 @@ describe Reactor::Subscriber do
|
|
27
27
|
describe 'matcher' do
|
28
28
|
it 'can be set to star to bind to all events' do
|
29
29
|
MySubscriber.create!(event: '*')
|
30
|
-
MySubscriber.any_instance.should_receive(:fire).with(hash_including('random' => 'data', 'event' =>
|
30
|
+
MySubscriber.any_instance.should_receive(:fire).with(hash_including('random' => 'data', 'event' => 'this_event'))
|
31
31
|
Reactor::Event.publish(:this_event, {random: 'data'})
|
32
32
|
end
|
33
33
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- winfred
|
@@ -9,8 +9,36 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sidekiq
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 2.13.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 2.13.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: activerecord
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 3.2.13
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 3.2.13
|
14
42
|
- !ruby/object:Gem::Dependency
|
15
43
|
name: bundler
|
16
44
|
requirement: !ruby/object:Gem::Requirement
|