bellbro 0.0.10 → 0.1.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
  SHA1:
3
- metadata.gz: 41861361bc83b68a51bc52e215bc4807abf67d6a
4
- data.tar.gz: b29769f4efc8e9735bdef5901a95a8b530e080a3
3
+ metadata.gz: 2b9a986f01ee5802f9a0de0140f43326ebc03bdf
4
+ data.tar.gz: 9523ec14d089eecce4b14ec9a193cd8f42ddfe01
5
5
  SHA512:
6
- metadata.gz: 5dafcf250ba4889ba5167b9aa75889c733873a25617f88e1eb6ba7c2afa786547c2490fae1a72f48b92e84cf1eda16d60f1eeceb24a8728b27348376dd1eb9b1
7
- data.tar.gz: 23b14ea36b6a74aa2522fb98f79fecff069172dfa8b5dd4acbab297f473c0c8239850e80daf9ed8a26d24e8182c4069543aacbd6e5e6427beb14ce70fbdb9e60
6
+ metadata.gz: ab2080b1e3e50445ddcdcb2ad95d6ffc74f71cd35e5e85bfba8fc388c971da3d246312cd2a223ff1df1b7dab310cf4e936511114839d9943ec85dc1ae4f6b756
7
+ data.tar.gz: dd48e8a909e52659a22a55100c694b59b90354fe0c536b39c6b9247b7e8d6bbbeb6911b3815870f6555b61fc8dc0e0de3446b1ee297c28169cba62498e6f4cf1
@@ -0,0 +1,264 @@
1
+ module Bellbro
2
+ # Internal: Methods relating to supporting hooks around Sidekiq worker invocation.
3
+ module Hooks
4
+ def self.included(base)
5
+ base.class_eval do
6
+ extend ClassMethods
7
+ end
8
+ end
9
+
10
+ module ClassMethods
11
+ # Public: Declare hooks to run around worker invocation. The around
12
+ # method may be called multiple times; subsequent calls append declared
13
+ # hooks to existing around hooks.
14
+ #
15
+ # hooks - Zero or more Symbol method names representing instance methods
16
+ # to be called around worker invocation. Each instance method
17
+ # invocation receives an argument representing the next link in
18
+ # the around hook chain.
19
+ # block - An optional block to be executed as a hook. If given, the block
20
+ # is executed after methods corresponding to any given Symbols.
21
+ #
22
+ # Examples
23
+ #
24
+ # class MyWorker
25
+ # include Worker
26
+ #
27
+ # around :time_execution
28
+ #
29
+ # around do |worker|
30
+ # puts "started"
31
+ # worker.call
32
+ # puts "finished"
33
+ # end
34
+ #
35
+ # def call
36
+ # puts "called"
37
+ # end
38
+ #
39
+ # private
40
+ #
41
+ # def time_execution(worker)
42
+ # context.start_time = Time.now
43
+ # worker.call
44
+ # context.finish_time = Time.now
45
+ # end
46
+ # end
47
+ #
48
+ # Returns nothing.
49
+ def around(*hooks, &block)
50
+ hooks << block if block
51
+ hooks.each { |hook| around_hooks.push(hook) }
52
+ end
53
+
54
+ # Public: Declare hooks to run before Worker invocation. The before
55
+ # method may be called multiple times; subsequent calls append declared
56
+ # hooks to existing before hooks.
57
+ #
58
+ # hooks - Zero or more Symbol method names representing instance methods
59
+ # to be called before worker invocation.
60
+ # block - An optional block to be executed as a hook. If given, the block
61
+ # is executed after methods corresponding to any given Symbols.
62
+ #
63
+ # Examples
64
+ #
65
+ # class MyWorker
66
+ # include Worker
67
+ #
68
+ # before :set_start_time
69
+ #
70
+ # before do
71
+ # puts "started"
72
+ # end
73
+ #
74
+ # def call
75
+ # puts "called"
76
+ # end
77
+ #
78
+ # private
79
+ #
80
+ # def set_start_time
81
+ # context.start_time = Time.now
82
+ # end
83
+ # end
84
+ #
85
+ # Returns nothing.
86
+ def before(*hooks, &block)
87
+ hooks << block if block
88
+ hooks.each { |hook| before_hooks.push(hook) }
89
+ end
90
+
91
+ # Public: Declare hooks to run after Worker invocation. The after
92
+ # method may be called multiple times; subsequent calls prepend declared
93
+ # hooks to existing after hooks.
94
+ #
95
+ # hooks - Zero or more Symbol method names representing instance methods
96
+ # to be called after worker invocation.
97
+ # block - An optional block to be executed as a hook. If given, the block
98
+ # is executed before methods corresponding to any given Symbols.
99
+ #
100
+ # Examples
101
+ #
102
+ # class MyWorker
103
+ # include Worker
104
+ #
105
+ # after :set_finish_time
106
+ #
107
+ # after do
108
+ # puts "finished"
109
+ # end
110
+ #
111
+ # def call
112
+ # puts "called"
113
+ # end
114
+ #
115
+ # private
116
+ #
117
+ # def set_finish_time
118
+ # context.finish_time = Time.now
119
+ # end
120
+ # end
121
+ #
122
+ # Returns nothing.
123
+ def after(*hooks, &block)
124
+ hooks << block if block
125
+ hooks.each { |hook| after_hooks.unshift(hook) }
126
+ end
127
+
128
+ # Internal: An Array of declared hooks to run around Worker
129
+ # invocation. The hooks appear in the order in which they will be run.
130
+ #
131
+ # Examples
132
+ #
133
+ # class MyWorker
134
+ # include Worker
135
+ #
136
+ # around :time_execution, :use_transaction
137
+ # end
138
+ #
139
+ # MyWorker.around_hooks
140
+ # # => [:time_execution, :use_transaction]
141
+ #
142
+ # Returns an Array of Symbols and Procs.
143
+ def around_hooks
144
+ @around_hooks ||= []
145
+ end
146
+
147
+ # Internal: An Array of declared hooks to run before Worker
148
+ # invocation. The hooks appear in the order in which they will be run.
149
+ #
150
+ # Examples
151
+ #
152
+ # class MyWorker
153
+ # include Sidekiq::Worker
154
+ #
155
+ # before :set_start_time, :say_hello
156
+ # end
157
+ #
158
+ # MyWorker.before_hooks
159
+ # # => [:set_start_time, :say_hello]
160
+ #
161
+ # Returns an Array of Symbols and Procs.
162
+ def before_hooks
163
+ @before_hooks ||= []
164
+ end
165
+
166
+ # Internal: An Array of declared hooks to run before Worker
167
+ # invocation. The hooks appear in the order in which they will be run.
168
+ #
169
+ # Examples
170
+ #
171
+ # class MyWorker
172
+ # include Sidekiq::Worker
173
+ #
174
+ # after :set_finish_time, :say_goodbye
175
+ # end
176
+ #
177
+ # MyWorker.after_hooks
178
+ # # => [:say_goodbye, :set_finish_time]
179
+ #
180
+ # Returns an Array of Symbols and Procs.
181
+ def after_hooks
182
+ @after_hooks ||= []
183
+ end
184
+ end
185
+
186
+ private
187
+
188
+ # Internal: Run around, before and after hooks around yielded execution. The
189
+ # required block is surrounded with hooks and executed.
190
+ #
191
+ # Examples
192
+ #
193
+ # class MyProcessor
194
+ # include Bellbro::Hooks
195
+ #
196
+ # def process_with_hooks
197
+ # with_hooks do
198
+ # process
199
+ # end
200
+ # end
201
+ #
202
+ # def process
203
+ # puts "processed!"
204
+ # end
205
+ # end
206
+ #
207
+ # Returns nothing.
208
+ def with_hooks
209
+ run_around_hooks do
210
+ run_before_hooks
211
+ yield
212
+ run_after_hooks
213
+ end
214
+ end
215
+
216
+ # Internal: Run around hooks.
217
+ #
218
+ # Returns nothing.
219
+ def run_around_hooks(&block)
220
+ self.class.around_hooks.reverse.inject(block) { |chain, hook|
221
+ proc { run_hook(hook, chain) }
222
+ }.call
223
+ end
224
+
225
+ # Internal: Run before hooks.
226
+ #
227
+ # Returns nothing.
228
+ def run_before_hooks
229
+ run_hooks(self.class.before_hooks)
230
+ end
231
+
232
+ # Internal: Run after hooks.
233
+ #
234
+ # Returns nothing.
235
+ def run_after_hooks
236
+ run_hooks(self.class.after_hooks)
237
+ end
238
+
239
+ # Internal: Run a colection of hooks. The "run_hooks" method is the common
240
+ # interface by which collections of either before or after hooks are run.
241
+ #
242
+ # hooks - An Array of Symbol and Proc hooks.
243
+ #
244
+ # Returns nothing.
245
+ def run_hooks(hooks)
246
+ hooks.each { |hook| run_hook(hook) }
247
+ end
248
+
249
+ # Internal: Run an individual hook. The "run_hook" method is the common
250
+ # interface by which an individual hook is run. If the given hook is a
251
+ # symbol, the method is invoked whether public or private. If the hook is a
252
+ # proc, the proc is evaluated in the context of the current instance.
253
+ #
254
+ # hook - A Symbol or Proc hook.
255
+ # args - Zero or more arguments to be passed as block arguments into the
256
+ # given block or as arguments into the method described by the given
257
+ # Symbol method name.
258
+ #
259
+ # Returns nothing.
260
+ def run_hook(hook, *args)
261
+ hook.is_a?(Symbol) ? send(hook, *args) : instance_exec(*args, &hook)
262
+ end
263
+ end
264
+ end
@@ -5,11 +5,27 @@ module Bellbro
5
5
  include Bellbro::SidekiqUtils
6
6
  include Bellbro::Trackable
7
7
 
8
- SLEEP_INTERVAL = defined?(Rails) && Rails.env.test? ? 1 : 3600
9
- track_with_schema jobs_started: Integer
10
-
11
8
  attr_reader :thread, :thread_error, :jid
12
9
 
10
+ def self.poll_interval(arg)
11
+ if defined?(Rails) && Rails.env.test?
12
+ @sleep_interval = 0.5
13
+ else
14
+ @sleep_interval = arg
15
+ end
16
+ end
17
+
18
+ def self.worker_class(arg)
19
+ @worker_class = arg
20
+ end
21
+
22
+ def self.get_worker_class
23
+ @worker_class
24
+ end
25
+
26
+ poll_interval defined?(Rails) && Rails.env.test? ? 1 : 3600
27
+ track_with_schema jobs_started: Integer
28
+
13
29
  def initialize
14
30
  @done = false
15
31
  @jid = Digest::MD5.hexdigest(Time.now.utc.to_s + Thread.current.object_id.to_s)
@@ -40,20 +56,23 @@ module Bellbro
40
56
  begin
41
57
  start_jobs
42
58
  Service.mutex.synchronize { status_update }
43
- sleep self.class::SLEEP_INTERVAL
59
+ sleep
44
60
  end until @done
45
61
  Service.mutex.synchronize { stop_tracking }
46
62
  end
47
63
 
48
64
  def start_jobs
49
65
  each_job do |job|
50
- klass = job[:klass].constantize
51
- jid = klass.perform_async(job[:arguments])
52
- ring "Starting job #{jid} #{job[:klass]} with #{job[:arguments]}."
66
+ jid = worker_class.perform_async(job)
67
+ ring "Starting job #{jid} #{worker_class.name} with #{job.inspect}."
53
68
  record_incr(:jobs_started)
54
69
  end
55
70
  end
56
71
 
72
+ def sleep
73
+ super(self.class.sleep_interval)
74
+ end
75
+
57
76
  def each_job
58
77
  # Override
59
78
  []
@@ -63,9 +82,18 @@ module Bellbro
63
82
  !@done
64
83
  end
65
84
 
85
+ def worker_class
86
+ @worker_class ||= self.class.get_worker_class
87
+ end
88
+
66
89
  def self.mutex
67
90
  $mutex ||= Mutex.new
68
91
  end
92
+
93
+ def self.sleep_interval
94
+ @sleep_interval
95
+ end
96
+
69
97
  end
70
98
 
71
99
  end
@@ -1,6 +1,44 @@
1
1
  module Bellbro
2
2
  module SidekiqUtils
3
3
 
4
+ def _workers
5
+ retryable(on: Redis::TimeoutError) do
6
+ workers_for_class("#{self.name}")
7
+ end
8
+ end
9
+
10
+ def _jobs
11
+ retryable(on: Redis::TimeoutError) do
12
+ jobs_for_class("#{self.name}")
13
+ end
14
+ end
15
+
16
+ def active_workers
17
+ _workers.map do |w|
18
+ {
19
+ :domain => worker_domain(w),
20
+ :jid => worker_jid(w),
21
+ :time => worker_time(w)
22
+ }
23
+ end
24
+ end
25
+
26
+ def queued_jobs
27
+ _jobs.map { |j| {:domain => job_domain(j), :jid => job_jid(j)} }
28
+ end
29
+
30
+ def workers_with_domain(domain)
31
+ active_workers.select { |w| w[:domain] == domain }
32
+ end
33
+
34
+ def jobs_with_domain(domain)
35
+ queued_jobs.select { |j| j[:domain] == domain }
36
+ end
37
+
38
+ def jobs_in_flight_with_domain(domain)
39
+ jobs_with_domain(domain) + workers_with_domain(domain)
40
+ end
41
+
4
42
  def workers
5
43
  Sidekiq::Workers.new.map do |process_id, thread_id, worker|
6
44
  worker
@@ -4,17 +4,19 @@ module Bellbro
4
4
 
5
5
  attr_reader :record
6
6
 
7
- def self.included(klass)
8
- class << klass
9
- def track_with_schema(hash)
10
- self.class_eval do
11
- @log_record_schema = hash
12
- end
13
- end
7
+ def self.included(base)
8
+ base.class_eval do
9
+ extend ClassMethods
10
+ end
11
+ end
14
12
 
15
- def log_record_schema
16
- @log_record_schema
17
- end
13
+ module ClassMethods
14
+ def track_with_schema(hash)
15
+ @log_record_schema = hash
16
+ end
17
+
18
+ def log_record_schema
19
+ @log_record_schema
18
20
  end
19
21
  end
20
22
 
@@ -25,11 +27,12 @@ module Bellbro
25
27
  @write_interval = opts[:write_interval] || 500
26
28
  @count = 0
27
29
  @tracking = true
28
- initialize_log_record
30
+ initialize_log_record if @log_record_schema
29
31
  status_update(true)
30
32
  end
31
33
 
32
34
  def status_update(force = false)
35
+ return unless @log_record_schema && Bellbro.logger
33
36
  return unless force || ((@count += 1) % @write_interval) == 0
34
37
  retryable { write_log(@record.to_json) }
35
38
  end
@@ -1,3 +1,3 @@
1
1
  module Bellbro
2
- VERSION = '0.0.10'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -2,68 +2,46 @@ module Bellbro
2
2
  class Worker < Bellbro::Bell
3
3
  include Sidekiq::Worker
4
4
  include Bellbro::Trackable
5
+ include Bellbro::Hooks
5
6
  extend Bellbro::SidekiqUtils
6
7
 
7
- attr_reader :domain
8
+ attr_reader :context
8
9
 
9
- def init(opts)
10
- # override
10
+ def perform(args)
11
+ return unless args.present?
12
+ set_context(args)
13
+ run_before_hooks
14
+ return unless should_run?
15
+ call
16
+ run_after_hooks
11
17
  end
12
18
 
13
- def perform(opts)
19
+ def call
14
20
  # override
15
21
  end
16
22
 
17
- def clean_up
23
+ def should_run?
18
24
  # override
25
+ self.class.should_run?
19
26
  end
20
27
 
21
- def transition
22
- # override
28
+ def debug?
29
+ @debug ||= !!context[:debug] rescue false
23
30
  end
24
31
 
25
- def i_am_alone_with_this_domain?
26
- self.class.jobs_with_domain(@domain).select { |j| jid != j[:jid] }.empty? &&
27
- self.class.workers_with_domain(@domain).select { |j| jid != j[:jid] }.empty?
28
- end
29
-
30
- def self._workers
31
- retryable(on: Redis::TimeoutError) do
32
- workers_for_class("#{self.name}")
33
- end
32
+ def self.should_run?
33
+ # override
34
+ true
34
35
  end
35
36
 
36
- def self._jobs
37
- retryable(on: Redis::TimeoutError) do
38
- jobs_for_class("#{self.name}")
39
- end
40
- end
37
+ private
41
38
 
42
- def self.active_workers
43
- _workers.map do |w|
44
- {
45
- :domain => worker_domain(w),
46
- :jid => worker_jid(w),
47
- :time => worker_time(w)
48
- }
39
+ def set_context(args)
40
+ if args.is_a?(Hash)
41
+ @context = args.symbolize_keys
42
+ else
43
+ @context = args
49
44
  end
50
45
  end
51
-
52
- def self.queued_jobs
53
- _jobs.map { |j| {:domain => job_domain(j), :jid => job_jid(j)} }
54
- end
55
-
56
- def self.workers_with_domain(domain)
57
- active_workers.select { |w| w[:domain] == domain }
58
- end
59
-
60
- def self.jobs_with_domain(domain)
61
- queued_jobs.select { |j| j[:domain] == domain }
62
- end
63
-
64
- def self.jobs_in_flight_with_domain(domain)
65
- jobs_with_domain(domain) + workers_with_domain(domain)
66
- end
67
46
  end
68
-
69
47
  end
data/lib/bellbro.rb CHANGED
@@ -9,6 +9,7 @@ require 'airbrake'
9
9
 
10
10
  %w(
11
11
  bellbro/settings.rb
12
+ bellbro/hooks.rb
12
13
  bellbro/retryable.rb
13
14
  bellbro/ringable.rb
14
15
  bellbro/trackable.rb
@@ -10,10 +10,6 @@ class TrackWorker < Bellbro::Worker
10
10
  status: String
11
11
  )
12
12
 
13
- def initialize(domain)
14
- @domain = domain
15
- end
16
-
17
13
  def jid
18
14
  "abc123"
19
15
  end
@@ -21,7 +17,7 @@ end
21
17
 
22
18
  describe Bellbro::Trackable do
23
19
  before :each do
24
- @worker = TrackWorker.new('www.retailer.com')
20
+ @worker = TrackWorker.new
25
21
  Sidekiq::Worker.clear_all
26
22
  end
27
23
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bellbro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Stokes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-07 00:00:00.000000000 Z
11
+ date: 2015-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -137,6 +137,7 @@ files:
137
137
  - bellbro.gemspec
138
138
  - lib/bellbro.rb
139
139
  - lib/bellbro/bell.rb
140
+ - lib/bellbro/hooks.rb
140
141
  - lib/bellbro/pool.rb
141
142
  - lib/bellbro/retryable.rb
142
143
  - lib/bellbro/ringable.rb