queue-bus 0.11.0 → 0.13.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.mdown +10 -0
- data/lib/queue_bus/application.rb +35 -8
- data/lib/queue_bus/dispatch.rb +39 -0
- data/lib/queue_bus/version.rb +1 -1
- data/spec/dispatch_spec.rb +154 -0
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48a236d7a44dafb099dc3d36e5f34e4a1f065d47fa76b3be1a7465ae8533773b
|
4
|
+
data.tar.gz: c2e6cffeba50ae36e13c8c417f43c7b9f18ff09772c4fd3ffd48e2784a80d5d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c3ba54737925161ec4c658864a7badd08f58400e246f31ee31a2aef7a6347005f073f62c2a3874aaf4e64f11a3da7f0a2fff322997e0a99da9b7901079e320a
|
7
|
+
data.tar.gz: 26b7011be9db57d5f2c93f397fda77374f8aa34fa097efc93d3831ce1832a3c1e12913433e507cf2c8e5c1057178e71b08a3fdbcee68fe382597b8bd3828f603
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.13.2]
|
10
|
+
|
11
|
+
### Fixes
|
12
|
+
|
13
|
+
- Properly passes the attributes down to the subscription when using `on_heartbeat`
|
14
|
+
|
15
|
+
## [0.13.1]
|
16
|
+
|
17
|
+
### Fixes
|
18
|
+
|
19
|
+
- Allows matching on 0 via the `on_heartbeat` subscription
|
20
|
+
|
21
|
+
### Added
|
22
|
+
|
23
|
+
- Allows matching on `wday` via the `on_heartbeat` subscription
|
24
|
+
|
25
|
+
## [0.13.0]
|
26
|
+
|
27
|
+
### Added
|
28
|
+
|
29
|
+
- Adds `Dispatch#on_heartbeat` which is a helper function for specifying heartbeat subscriptions.
|
30
|
+
|
31
|
+
## [0.12.0]
|
32
|
+
|
33
|
+
### Changed
|
34
|
+
- Pipelines fetching all queue subscriptions when using `QueueBus::Application.all`
|
35
|
+
|
9
36
|
## [0.11.0]
|
10
37
|
|
11
38
|
### Added
|
data/README.mdown
CHANGED
@@ -63,6 +63,16 @@ QueueBus.dispatch("app_b") do
|
|
63
63
|
subscribe "my_key", { "user_id" => :present, "page" => "homepage"} do
|
64
64
|
Mixpanel.homepage_action!(attributes["action"])
|
65
65
|
end
|
66
|
+
|
67
|
+
# You may also declare a subscription to heartbeat events. This is a helper function
|
68
|
+
# that works along with subscribe to make scheduling regular events easier.
|
69
|
+
#
|
70
|
+
# minute_interval: Executes every n minutes
|
71
|
+
# hour_interval: Executes every n hours
|
72
|
+
# minute: Executes on this minute
|
73
|
+
# hour: Executes on this hour
|
74
|
+
on_heartbeat "my_heartbeat_event", minute_interval: 5 do |attributes|
|
75
|
+
end
|
66
76
|
end
|
67
77
|
```
|
68
78
|
|
@@ -7,7 +7,22 @@ module QueueBus
|
|
7
7
|
class << self
|
8
8
|
def all
|
9
9
|
# note the names arent the same as we started with
|
10
|
-
::QueueBus.redis
|
10
|
+
::QueueBus.redis do |redis|
|
11
|
+
app_keys = redis.smembers(app_list_key)
|
12
|
+
apps = app_keys.collect { |val| new(val) }
|
13
|
+
|
14
|
+
hashes = redis.pipelined do
|
15
|
+
apps.each do |app|
|
16
|
+
redis.hgetall(app.redis_key)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
apps.zip(hashes).each do |app, hash|
|
21
|
+
app._hydrate_redis_hash(hash)
|
22
|
+
end
|
23
|
+
|
24
|
+
apps
|
25
|
+
end
|
11
26
|
end
|
12
27
|
end
|
13
28
|
|
@@ -90,6 +105,10 @@ module QueueBus
|
|
90
105
|
out
|
91
106
|
end
|
92
107
|
|
108
|
+
def _hydrate_redis_hash(hash)
|
109
|
+
@raw_redis_hash = hash
|
110
|
+
end
|
111
|
+
|
93
112
|
protected
|
94
113
|
|
95
114
|
def self.normalize(val)
|
@@ -114,16 +133,24 @@ module QueueBus
|
|
114
133
|
|
115
134
|
def read_redis_hash
|
116
135
|
out = {}
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
out[key] = val
|
123
|
-
end
|
136
|
+
raw_redis_hash.each do |key, val|
|
137
|
+
begin
|
138
|
+
out[key] = ::QueueBus::Util.decode(val)
|
139
|
+
rescue ::QueueBus::Util::DecodeException
|
140
|
+
out[key] = val
|
124
141
|
end
|
125
142
|
end
|
126
143
|
out
|
127
144
|
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def raw_redis_hash
|
149
|
+
return @raw_redis_hash if @raw_redis_hash
|
150
|
+
|
151
|
+
::QueueBus.redis do |redis|
|
152
|
+
redis.hgetall(redis_key)
|
153
|
+
end
|
154
|
+
end
|
128
155
|
end
|
129
156
|
end
|
data/lib/queue_bus/dispatch.rb
CHANGED
@@ -16,6 +16,45 @@ module QueueBus
|
|
16
16
|
@subscriptions.size
|
17
17
|
end
|
18
18
|
|
19
|
+
def on_heartbeat(key, minute: nil, hour: nil, wday: nil, minute_interval: nil, hour_interval: nil, &block) # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/LineLength
|
20
|
+
if minute_interval && !minute_interval.positive?
|
21
|
+
raise ArgumentError, 'minute_interval must be a positive integer'
|
22
|
+
end
|
23
|
+
|
24
|
+
if hour_interval && !hour_interval.positive?
|
25
|
+
raise ArgumentError, 'hour_interval must be a positive integer'
|
26
|
+
end
|
27
|
+
|
28
|
+
matcher = { bus_event_type: :heartbeat_minutes }
|
29
|
+
|
30
|
+
if minute
|
31
|
+
raise ArgumentError, 'minute must not be negative' if minute.negative?
|
32
|
+
|
33
|
+
matcher['minute'] = minute
|
34
|
+
end
|
35
|
+
|
36
|
+
if hour
|
37
|
+
raise ArgumentError, 'hour must not be negative' if hour.negative?
|
38
|
+
|
39
|
+
matcher['hour'] = hour
|
40
|
+
end
|
41
|
+
|
42
|
+
if wday
|
43
|
+
raise ArgumentError, 'wday must not be negative' if wday.negative?
|
44
|
+
|
45
|
+
matcher['wday'] = wday
|
46
|
+
end
|
47
|
+
|
48
|
+
subscribe(key, matcher) do |event|
|
49
|
+
if (minute_interval.nil? || (event['minute'] % minute_interval).zero?) &&
|
50
|
+
(hour_interval.nil? || (event['hour'] % hour_interval).zero?)
|
51
|
+
|
52
|
+
# Yield the block passed in.
|
53
|
+
block.call(event)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
19
58
|
def subscribe(key, matcher_hash = nil, &block)
|
20
59
|
dispatch_event('default', key, matcher_hash, block)
|
21
60
|
end
|
data/lib/queue_bus/version.rb
CHANGED
data/spec/dispatch_spec.rb
CHANGED
@@ -28,6 +28,160 @@ module QueueBus
|
|
28
28
|
end.not_to raise_error
|
29
29
|
end
|
30
30
|
|
31
|
+
describe '#on_heartbeat' do
|
32
|
+
let(:dispatch) { Dispatch.new('heartbeat') }
|
33
|
+
let(:event) { { bus_event_type: :heartbeat_minutes } }
|
34
|
+
let(:event_name) { 'my-event' }
|
35
|
+
|
36
|
+
it 'passes on the event' do
|
37
|
+
dispatch.on_heartbeat event_name do |event|
|
38
|
+
expect(event).to match hash_including('hour' => 1, 'minute' => 0)
|
39
|
+
end
|
40
|
+
|
41
|
+
dispatch.execute(event_name, 'hour' => 1, 'minute' => 0)
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when not declaring anything' do
|
45
|
+
before do
|
46
|
+
dispatch.on_heartbeat event_name do |_event|
|
47
|
+
Runner2.run({})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'runs on every heart beat' do
|
52
|
+
(0..24).each do |hour|
|
53
|
+
(0..60).each do |minute|
|
54
|
+
expect do
|
55
|
+
dispatch.execute(
|
56
|
+
event_name, event.merge('hour' => hour, 'minute' => minute)
|
57
|
+
)
|
58
|
+
end.to change(Runner2, :value).by(1)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when running on hour 8' do
|
65
|
+
before do
|
66
|
+
dispatch.on_heartbeat event_name, hour: 8 do |_event|
|
67
|
+
Runner2.run({})
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'subscribes to hour 8' do
|
72
|
+
expect(dispatch.subscriptions.all.first.matcher.filters)
|
73
|
+
.to eq('bus_event_type' => 'heartbeat_minutes', 'hour' => '8')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when running on minute 4' do
|
78
|
+
before do
|
79
|
+
dispatch.on_heartbeat event_name, minute: 4 do |_event|
|
80
|
+
Runner2.run({})
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'subscribes to minute 4' do
|
85
|
+
expect(dispatch.subscriptions.all.first.matcher.filters)
|
86
|
+
.to eq('bus_event_type' => 'heartbeat_minutes', 'minute' => '4')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when running on minute 4 and hour 8' do
|
91
|
+
before do
|
92
|
+
dispatch.on_heartbeat event_name, hour: 8, minute: 4 do |_event|
|
93
|
+
Runner2.run({})
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'subscribes to minute 4 and hour 8' do
|
98
|
+
expect(dispatch.subscriptions.all.first.matcher.filters)
|
99
|
+
.to eq('bus_event_type' => 'heartbeat_minutes', 'minute' => '4', 'hour' => '8')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when running on wday 2' do
|
104
|
+
before do
|
105
|
+
dispatch.on_heartbeat event_name, wday: 2 do |_event|
|
106
|
+
Runner2.run({})
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'subscribes to wday 2' do
|
111
|
+
expect(dispatch.subscriptions.all.first.matcher.filters)
|
112
|
+
.to eq('bus_event_type' => 'heartbeat_minutes', 'wday' => '2')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when declaring minute intervals' do
|
117
|
+
before do
|
118
|
+
dispatch.on_heartbeat event_name, minute_interval: 5 do |_event|
|
119
|
+
Runner2.run({})
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'runs the runner when the minute buzzes (modulos to 5)' do
|
124
|
+
(0..60).each do |minute|
|
125
|
+
if minute % 5 == 0
|
126
|
+
expect { dispatch.execute(event_name, event.merge('minute' => minute)) }
|
127
|
+
.to change(Runner2, :value).by(1)
|
128
|
+
else
|
129
|
+
expect { dispatch.execute(event_name, event.merge('minute' => minute)) }
|
130
|
+
.not_to change(Runner2, :value)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'when declaring hour intervals' do
|
137
|
+
before do
|
138
|
+
dispatch.on_heartbeat event_name, hour_interval: 3 do |_event|
|
139
|
+
Runner2.run({})
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'runs the runner when the hour fizzes (modulos to 3)' do
|
144
|
+
(0..60).each do |hour|
|
145
|
+
if hour % 3 == 0
|
146
|
+
expect { dispatch.execute(event_name, event.merge('hour' => hour)) }
|
147
|
+
.to change(Runner2, :value).by(1)
|
148
|
+
else
|
149
|
+
expect { dispatch.execute(event_name, event.merge('hour' => hour)) }
|
150
|
+
.not_to change(Runner2, :value)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'when declaring hour and minute intervals' do
|
157
|
+
before do
|
158
|
+
dispatch.on_heartbeat event_name, minute_interval: 5, hour_interval: 3 do |_event|
|
159
|
+
Runner2.run({})
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'runs the runner when the time fizzbuzzes (modulos to 3 and 5)' do
|
164
|
+
(0..24).each do |hour|
|
165
|
+
(0..60).each do |minute|
|
166
|
+
if hour % 3 == 0 && minute % 5 == 0
|
167
|
+
expect do
|
168
|
+
dispatch.execute(
|
169
|
+
event_name, event.merge('hour' => hour, 'minute' => minute)
|
170
|
+
)
|
171
|
+
end.to change(Runner2, :value).by(1)
|
172
|
+
else
|
173
|
+
expect do
|
174
|
+
dispatch.execute(
|
175
|
+
event_name, event.merge('hour' => hour, 'minute' => minute)
|
176
|
+
)
|
177
|
+
end.not_to change(Runner2, :value)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
31
185
|
describe 'Top Level' do
|
32
186
|
before(:each) do
|
33
187
|
QueueBus.dispatch('testit') do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queue-bus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Leonard
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -159,7 +159,7 @@ files:
|
|
159
159
|
homepage: ''
|
160
160
|
licenses: []
|
161
161
|
metadata: {}
|
162
|
-
post_install_message:
|
162
|
+
post_install_message:
|
163
163
|
rdoc_options: []
|
164
164
|
require_paths:
|
165
165
|
- lib
|
@@ -174,9 +174,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
174
|
- !ruby/object:Gem::Version
|
175
175
|
version: '0'
|
176
176
|
requirements: []
|
177
|
-
|
178
|
-
|
179
|
-
signing_key:
|
177
|
+
rubygems_version: 3.0.3
|
178
|
+
signing_key:
|
180
179
|
specification_version: 4
|
181
180
|
summary: A simple event bus on top of background queues
|
182
181
|
test_files:
|