queue-bus 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 329cc0a74e428d99421a14c9b2b07e39e14ee98da5c43babceb51376d27006c6
4
- data.tar.gz: 2439e577df8ea33e2f959b49ddfc105858844080556c4431a47897667d87fa92
3
+ metadata.gz: 511b1d30315adbfe76e6fa303aaba3158d56d39bea93355a0d28c18c8b0578cb
4
+ data.tar.gz: ba55e76505d56b98a416ff60c64c2c384734cd18af332768f6631e490caf4ed5
5
5
  SHA512:
6
- metadata.gz: 2875311c4100923fc00886ac05e2b4053ec6bfff442114faa6cc6bf39698916234866f57ebcbeb09dbcaca85484ca3bb0ce88cdbf8eb5640f6ca3b46d88a5a23
7
- data.tar.gz: f7d88adffc92f2635b1068f47c68238787b55eea86d4302bc2579a40bc2c3ff4ce145d62688a7584a2b48fa31b03951b993757a0e3b65eb71a1b3a4715aeb741
6
+ metadata.gz: b0f0d47e2be417d33b1f396043fd604ff936d9a1f258550b725673b4a9649d6e6153edaca77a064996ab3f0c43b59849ab04a66c49f3afb4f2d058a7c788f1e3
7
+ data.tar.gz: 941c73b6e35945a181651bb03746fff2022947fe89102daebd76f72e211150dfd2382ebd41bbd35857b1c5b9a2f099389b25392ba8e0c210615b624ef5898fb0
data/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.13.0]
10
+
11
+ ### Added
12
+
13
+ - Adds `Dispatch#on_heartbeat` which is a helper function for specifying heartbeat subscriptions.
14
+
9
15
  ## [0.12.0]
10
16
 
11
17
  ### Changed
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
 
@@ -16,6 +16,39 @@ module QueueBus
16
16
  @subscriptions.size
17
17
  end
18
18
 
19
+ def on_heartbeat(key, minute: nil, hour: nil, minute_interval: nil, hour_interval: nil, &block) # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/ParameterLists, Metrics/CyclomaticComplexity, Metrics/AbcSize
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 be a positive integer' unless minute.positive?
32
+
33
+ matcher['minute'] = minute
34
+ end
35
+
36
+ if hour
37
+ raise ArgumentError, 'hour must be a positive integer' unless hour.positive?
38
+
39
+ matcher['hour'] = hour
40
+ end
41
+
42
+ subscribe(key, matcher) do |event|
43
+ if (minute_interval.nil? || (event['minute'] % minute_interval).zero?) &&
44
+ (hour_interval.nil? || (event['hour'] % hour_interval).zero?)
45
+
46
+ # Yield the block passed in.
47
+ block.call
48
+ end
49
+ end
50
+ end
51
+
19
52
  def subscribe(key, matcher_hash = nil, &block)
20
53
  dispatch_event('default', key, matcher_hash, block)
21
54
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module QueueBus
4
- VERSION = '0.12.0'
4
+ VERSION = '0.13.0'
5
5
  end
@@ -28,6 +28,137 @@ 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
+ context 'when not declaring anything' do
37
+ before do
38
+ dispatch.on_heartbeat event_name do |_event|
39
+ Runner2.run({})
40
+ end
41
+ end
42
+
43
+ it 'runs on every heart beat' do
44
+ (0..24).each do |hour|
45
+ (0..60).each do |minute|
46
+ expect do
47
+ dispatch.execute(
48
+ event_name, event.merge('hour' => hour, 'minute' => minute)
49
+ )
50
+ end.to change(Runner2, :value).by(1)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'when running on hour 8' do
57
+ before do
58
+ dispatch.on_heartbeat event_name, hour: 8 do |_event|
59
+ Runner2.run({})
60
+ end
61
+ end
62
+
63
+ it 'subscribes to hour 8' do
64
+ expect(dispatch.subscriptions.all.first.matcher.filters).to eq('bus_event_type' => 'heartbeat_minutes', 'hour' => '8')
65
+ end
66
+ end
67
+
68
+ context 'when running on minute 4' do
69
+ before do
70
+ dispatch.on_heartbeat event_name, minute: 4 do |_event|
71
+ Runner2.run({})
72
+ end
73
+ end
74
+
75
+ it 'subscribes to minute 4' do
76
+ expect(dispatch.subscriptions.all.first.matcher.filters).to eq('bus_event_type' => 'heartbeat_minutes', 'minute' => '4')
77
+ end
78
+ end
79
+
80
+ context 'when running on minute 4 and hour 8' do
81
+ before do
82
+ dispatch.on_heartbeat event_name, hour: 8, minute: 4 do |_event|
83
+ Runner2.run({})
84
+ end
85
+ end
86
+
87
+ it 'subscribes to minute 4 and hour 8' do
88
+ expect(dispatch.subscriptions.all.first.matcher.filters)
89
+ .to eq('bus_event_type' => 'heartbeat_minutes', 'minute' => '4', 'hour' => '8')
90
+ end
91
+ end
92
+
93
+ context 'when declaring minute intervals' do
94
+ before do
95
+ dispatch.on_heartbeat event_name, minute_interval: 5 do |_event|
96
+ Runner2.run({})
97
+ end
98
+ end
99
+
100
+ it 'runs the runner when the minute buzzes (modulos to 5)' do
101
+ (0..60).each do |minute|
102
+ if minute % 5 == 0
103
+ expect { dispatch.execute(event_name, event.merge('minute' => minute)) }
104
+ .to change(Runner2, :value).by(1)
105
+ else
106
+ expect { dispatch.execute(event_name, event.merge('minute' => minute)) }
107
+ .not_to change(Runner2, :value)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ context 'when declaring hour intervals' do
114
+ before do
115
+ dispatch.on_heartbeat event_name, hour_interval: 3 do |_event|
116
+ Runner2.run({})
117
+ end
118
+ end
119
+
120
+ it 'runs the runner when the hour fizzes (modulos to 3)' do
121
+ (0..60).each do |hour|
122
+ if hour % 3 == 0
123
+ expect { dispatch.execute(event_name, event.merge('hour' => hour)) }
124
+ .to change(Runner2, :value).by(1)
125
+ else
126
+ expect { dispatch.execute(event_name, event.merge('hour' => hour)) }
127
+ .not_to change(Runner2, :value)
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ context 'when declaring hour and minute intervals' do
134
+ before do
135
+ dispatch.on_heartbeat event_name, minute_interval: 5, hour_interval: 3 do |_event|
136
+ Runner2.run({})
137
+ end
138
+ end
139
+
140
+ it 'runs the runner when the time fizzbuzzes (modulos to 3 and 5)' do
141
+ (0..24).each do |hour|
142
+ (0..60).each do |minute|
143
+ if hour % 3 == 0 && minute % 5 == 0
144
+ expect do
145
+ dispatch.execute(
146
+ event_name, event.merge('hour' => hour, 'minute' => minute)
147
+ )
148
+ end.to change(Runner2, :value).by(1)
149
+ else
150
+ expect do
151
+ dispatch.execute(
152
+ event_name, event.merge('hour' => hour, 'minute' => minute)
153
+ )
154
+ end.not_to change(Runner2, :value)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+
31
162
  describe 'Top Level' do
32
163
  before(:each) do
33
164
  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.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Leonard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-16 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json