bellbro 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ab7478116c23d04ae5d103a43267dc6ad90563c
4
- data.tar.gz: 259f5b67b770f5d6a4fa997eac99c3d2cb17ca92
3
+ metadata.gz: ad4922093fc7d4fb69b7de03b4a022637783660e
4
+ data.tar.gz: 42b446096f63c27560a1269f8e4d92d59bc5e6f1
5
5
  SHA512:
6
- metadata.gz: 3d6c331e559941c713cacf0e4325bc5a55742b953c10d5a82494cd8cc8d6b98da78127e262e0877af93e43fae4aeeb4da6dbd112b40fe3f946ff79ac28e6523d
7
- data.tar.gz: 39a37fb409cf9005de5b7ec609b7f6afb382e519eda35ec8bf1716e51c199c504c074a0764c72c36d7c9b5e90cdf5df59c6a289cd31dc6401dcff32d995434e4
6
+ metadata.gz: 2018607f4643fe88d4c04ea086291a35d35615f93d14c139caad7616c4e90ec0a92f3ff44dcb0d42269c2d1b140d5ead5b3782c4dfc930dacfa8ab80ac77bcb9
7
+ data.tar.gz: 1e6eefd6c7f3f312802f16831147a822eba4a5820debc0c9c13656322d16f19cff1a0a6d44feb271ae593e907bab226c77ca9630b655a9f9a825e0bce06aed28
data/Gemfile CHANGED
@@ -1,6 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'shout', path: '../shout'
4
-
5
3
  # Specify your gem's dependencies in bellbro.gemspec
6
4
  gemspec
@@ -7,14 +7,16 @@ require 'digest'
7
7
  require 'sidekiq'
8
8
  require 'airbrake'
9
9
  require 'retryable'
10
- require 'shout'
11
10
 
12
11
  %w(
13
- bellbro/hooks.rb
14
- bellbro/trackable.rb
15
- bellbro/sidekiq_utils.rb
16
- bellbro/service.rb
17
- bellbro/worker.rb
12
+ bellbro/settings.rb
13
+ bellbro/timer.rb
14
+ bellbro/hooks.rb
15
+ bellbro/ringable.rb
16
+ bellbro/trackable.rb
17
+ bellbro/sidekiq_utils.rb
18
+ bellbro/service.rb
19
+ bellbro/worker.rb
18
20
  ).each do |path|
19
21
  require File.join(File.dirname(__FILE__),path)
20
- end
22
+ end
@@ -11,7 +11,15 @@ module Bellbro
11
11
  end
12
12
 
13
13
  def abort!
14
- !(@abort = true)
14
+ @abort = true
15
+ end
16
+
17
+ def timer
18
+ @timer ||= Bellbro::Timer.new(self.class.time_out_interval)
19
+ end
20
+
21
+ def timed_out?
22
+ timer.timed_out?
15
23
  end
16
24
  end
17
25
 
@@ -59,6 +67,14 @@ module Bellbro
59
67
  hooks.each { |hook| around_hooks.push(hook) }
60
68
  end
61
69
 
70
+ def time_out_in(interval)
71
+ @time_out_interval = interval
72
+ end
73
+
74
+ def time_out_interval
75
+ @time_out_interval
76
+ end
77
+
62
78
  # Public: Declare hooks to run before Worker invocation. The before
63
79
  # method may be called multiple times; subsequent calls append declared
64
80
  # hooks to existing before hooks.
@@ -130,7 +146,7 @@ module Bellbro
130
146
  # Returns nothing.
131
147
  def after(*hooks, &block)
132
148
  hooks << block if block
133
- hooks.each { |hook| after_hooks.unshift(hook) }
149
+ hooks.each { |hook| after_hooks.push(hook) }
134
150
  end
135
151
 
136
152
  def always(*hooks, &block)
@@ -0,0 +1,22 @@
1
+ module Bellbro
2
+ module Ringable
3
+ def self.included(klass)
4
+ klass.extend(self)
5
+ end
6
+
7
+ def self.logger
8
+ Bellbro::Settings.logger
9
+ end
10
+
11
+ def error(log_line)
12
+ ring(log_line, type: :error)
13
+ end
14
+
15
+ def ring(log_line, opts={})
16
+ domain_insert = @domain ? "[#{@domain}]": ""
17
+ error_insert = (opts[:type] == :error) ? "PlatformError " : ""
18
+ complete_log_line = "[#{self.class}](#{Thread.current.object_id})#{domain_insert}: #{error_insert}#{log_line}"
19
+ Bellbro::Settings.logger.info complete_log_line
20
+ end
21
+ end
22
+ end
@@ -4,7 +4,7 @@ module Bellbro
4
4
  class Service
5
5
  include Bellbro::SidekiqUtils
6
6
  include Bellbro::Trackable
7
- include Shout
7
+ include Bellbro::Ringable
8
8
 
9
9
  attr_reader :thread, :thread_error, :jid
10
10
 
@@ -36,23 +36,23 @@ module Bellbro
36
36
  @thread = Thread.new do
37
37
  begin
38
38
  run
39
- rescue Exception => @thread_error
40
- log "#{@thread_error.inspect}", type: :error
41
- Airbrake.notify(@thread_error)
42
- raise @thread_error
39
+ #rescue Exception => @thread_error
40
+ # Rails.logger.info "#{@thread_error.inspect}", type: :error
41
+ # Airbrake.notify(@thread_error)
42
+ # raise @thread_error
43
43
  end
44
44
  end
45
45
  end
46
46
 
47
47
  def stop
48
48
  @done = true
49
- log "Stopping #{self.class} service..."
49
+ Rails.logger.info "Stopping #{self.class} service..."
50
50
  @thread.join
51
- log "#{self.class.to_s.capitalize} service stopped."
51
+ Rails.logger.info "#{self.class.to_s.capitalize} service stopped."
52
52
  end
53
53
 
54
54
  def run
55
- log "Starting #{self.class} service."
55
+ Rails.logger.info "Starting #{self.class} service."
56
56
  self.class.mutex.synchronize { track }
57
57
  begin
58
58
  self.class.mutex.synchronize { start_jobs }
@@ -65,7 +65,7 @@ module Bellbro
65
65
  def start_jobs
66
66
  each_job do |job|
67
67
  jid = worker_class.perform_async(job)
68
- log "Starting job #{jid} #{worker_class.name} with #{job.inspect}."
68
+ Rails.logger.info "Starting job #{jid} #{worker_class.name} with #{job.inspect}."
69
69
  record_incr(:jobs_started)
70
70
  end
71
71
  end
@@ -0,0 +1,24 @@
1
+ module Bellbro
2
+ module Settings
3
+
4
+ class SettingsData < Struct.new(:logger)
5
+ end
6
+
7
+ def self.configuration
8
+ @configuration ||= Bellbro::Settings::SettingsData.new
9
+ end
10
+
11
+ def self.configure
12
+ yield configuration
13
+ end
14
+
15
+ def self.logger
16
+ return unless configured?
17
+ configuration.logger
18
+ end
19
+
20
+ def self.configured?
21
+ !!configuration
22
+ end
23
+ end
24
+ end
@@ -3,112 +3,143 @@ require 'retryable'
3
3
  module Bellbro
4
4
  module SidekiqUtils
5
5
 
6
- def _workers
7
- Retryable.retryable(on: Redis::TimeoutError) do
8
- workers_for_class("#{self.name}")
6
+ class Queue
7
+ def self.names
8
+ Sidekiq::Stats::Queues.new.lengths.keys
9
9
  end
10
- end
11
10
 
12
- def _jobs
13
- Retryable.retryable(on: Redis::TimeoutError) do
14
- jobs_for_class("#{self.name}")
11
+ def self.all
12
+ names.map do |name|
13
+ Sidekiq::Queue.new(name)
14
+ end
15
15
  end
16
- end
17
16
 
18
- def active_workers
19
- _workers.map do |w|
20
- {
21
- :domain => worker_domain(w),
22
- :jid => worker_jid(w),
23
- :time => worker_time(w)
24
- }
17
+ def self.each
18
+ names.each do |name|
19
+ yield Sidekiq::Queue.new(name)
20
+ end
25
21
  end
26
- end
27
22
 
28
- def queued_jobs
29
- _jobs.map { |j| {:domain => job_domain(j), :jid => job_jid(j)} }
23
+ def self.clear_all
24
+ each do |q|
25
+ q.clear
26
+ end
27
+ end
30
28
  end
31
29
 
32
- def workers_with_domain(domain)
33
- active_workers.select { |w| w[:domain] == domain }
34
- end
30
+ class Job
31
+ attr_accessor :source
35
32
 
36
- def jobs_with_domain(domain)
37
- queued_jobs.select { |j| j[:domain] == domain }
38
- end
33
+ def initialize(source)
34
+ @source = source
35
+ end
39
36
 
40
- def jobs_in_flight_with_domain(domain)
41
- jobs_with_domain(domain) + workers_with_domain(domain)
42
- end
37
+ def method_missing(method_name, *args, &block)
38
+ source.args.first.try(:[], method_name.to_s)
39
+ end
43
40
 
44
- def workers
45
- Sidekiq::Workers.new.map do |process_id, thread_id, worker|
46
- worker
41
+ def jid
42
+ source.jid
47
43
  end
48
- end
49
44
 
50
- def workers_for_queue(q)
51
- workers.select do |worker|
52
- worker_queue(worker) == q
45
+ def self.all_for_class(klass_name)
46
+ Retryable.retryable(on: Redis::TimeoutError) do
47
+ Queue.all.map do |q|
48
+ q.map do |job|
49
+ next unless job.klass == klass_name
50
+ new(job)
51
+ end
52
+ end.flatten.compact
53
+ end
53
54
  end
54
55
  end
55
56
 
56
- def workers_for_class(klass)
57
- workers.select do |worker|
58
- worker_class(worker) == klass
57
+ class Worker
58
+ attr_accessor :source
59
+
60
+ def initialize(source)
61
+ @source = source
59
62
  end
60
- end
61
63
 
62
- def worker_jid(worker)
63
- worker["payload"]["jid"] if worker["payload"]
64
- end
64
+ def method_missing(method_name, *args, &block)
65
+ args.first.try(:[],method_name.to_s)
66
+ end
65
67
 
66
- def worker_domain(worker)
67
- worker["payload"]["args"].first["domain"] if worker["payload"] && worker["payload"]["args"].try(:any?)
68
- end
68
+ def payload
69
+ source["payload"] || {}
70
+ end
69
71
 
70
- def worker_time(worker)
71
- worker["run_at"]
72
- end
72
+ def args
73
+ payload["args"] || []
74
+ end
73
75
 
74
- def worker_class(worker)
75
- worker["payload"]["class"] if worker["payload"]
76
- end
76
+ def jid
77
+ payload["jid"]
78
+ end
77
79
 
78
- def worker_queue(worker)
79
- worker["queue"]
80
- end
80
+ def time
81
+ source["run_at"]
82
+ end
81
83
 
82
- def jobs_for_queue(q)
83
- Sidekiq::Queue.new(q)
84
+ def klass
85
+ payload["class"]
86
+ end
87
+
88
+ def queue
89
+ source["queue"]
90
+ end
91
+
92
+ def self.all
93
+ Sidekiq::Workers.new.map do |process_id, thread_id, worker|
94
+ worker
95
+ end
96
+ end
97
+
98
+ def self.all_for_class(klass_name)
99
+ Retryable.retryable(on: Redis::TimeoutError) do
100
+ all.select do |worker|
101
+ worker.klass == klass_name
102
+ end
103
+ end
104
+ end
84
105
  end
85
106
 
86
- def jobs_for_class(klass)
87
- queues.map do |q|
88
- jobs_for_queue(q).select { |job| job.klass == klass }
89
- end.flatten
107
+ def workers
108
+ Worker.all_for_class("#{self.name}")
90
109
  end
91
110
 
92
- def job_domain(job)
93
- job.args.first["domain"] if job.args.any?
111
+ def jobs
112
+ Job.all_for_class("#{self.name}")
94
113
  end
95
114
 
96
- def job_jid(job)
97
- job.jid
115
+ def jobs_in_flight_with(arg)
116
+ jobs_with(arg) + workers_with(arg)
98
117
  end
99
118
 
100
- def number_of_active_workers(q_name)
101
- workers_for_queue(q_name).count
119
+ def jobs_with(arg)
120
+ key = arg.keys.first
121
+ value = arg.values.first
122
+ jobs.select do |job|
123
+ value == job.send(key)
124
+ end
102
125
  end
103
126
 
104
- def queues
105
- Sidekiq::Stats::Queues.new.lengths.keys
127
+ def workers_with(arg)
128
+ key = arg.keys.first
129
+ value = arg.values.first
130
+ workers.select do |worker|
131
+ value == worker.send(key)
132
+ end
106
133
  end
107
134
 
108
- def clear_all_queues
109
- queues.each do |q|
110
- clear_queue(q)
135
+ def workers_for_queue(q)
136
+ workers.select do |worker|
137
+ worker.queue == q
111
138
  end
112
139
  end
140
+
141
+ def number_of_active_workers(q_name)
142
+ workers_for_queue(q_name).count
143
+ end
113
144
  end
114
- end
145
+ end
@@ -0,0 +1,14 @@
1
+ module Bellbro
2
+ class Timer
3
+ attr_reader :limit, :started
4
+
5
+ def initialize(limit=nil)
6
+ @limit ||= 1.hour
7
+ @started = Time.current
8
+ end
9
+
10
+ def timed_out?
11
+ Time.current - started > limit
12
+ end
13
+ end
14
+ end
@@ -30,13 +30,21 @@ module Bellbro
30
30
  end
31
31
 
32
32
  def status_update(force = false)
33
- return unless @log_record_schema && Shout.logger
33
+ return unless @log_record_schema && Bellbro::Settings.logger
34
34
  return unless force || ((@count += 1) % @write_interval) == 0
35
- Retryable.retryable { write_log(@record.to_json) }
35
+ line = Rails.env.test? ? JSON.pretty_generate(@record) : @record.to_json
36
+ Retryable.retryable { write_log(line) }
36
37
  end
37
38
 
38
39
  def write_log(line)
39
- Shout.logger.info line
40
+ ring line
41
+ end
42
+
43
+ def record_update(attrs)
44
+ attrs.symbolize_keys!
45
+ attrs.each do |attr, value|
46
+ record_set(attr, value)
47
+ end
40
48
  end
41
49
 
42
50
  def record_set(attr, value)
@@ -45,10 +53,14 @@ module Bellbro
45
53
  @record[:data][attr] = value
46
54
  end
47
55
 
48
- def record_incr(attr)
56
+ def record_add(attr, num)
49
57
  attr = attr.to_sym
50
- validate(attr => 1)
51
- @record[:data][attr] += 1
58
+ validate(attr => num)
59
+ @record[:data][attr] += num
60
+ end
61
+
62
+ def record_incr(attr)
63
+ record_add(attr, 1)
52
64
  end
53
65
 
54
66
  def stop_tracking
@@ -56,6 +68,7 @@ module Bellbro
56
68
  @record[:stopped] = Time.now.utc.iso8601
57
69
  @tracking = false
58
70
  status_update(true)
71
+ @record = nil
59
72
  end
60
73
 
61
74
  def tracking?
@@ -94,9 +107,9 @@ module Bellbro
94
107
  def validate(attrs)
95
108
  attrs.each do |attr, value|
96
109
  raise "Invalid attribute #{attr}" unless log_record_attributes.include?(attr)
97
- raise "Invalid type for #{attr}" unless [value.class, value.class.superclass].include?(@log_record_schema[attr])
110
+ raise "Invalid type for #{attr}. Value #{value} is a #{value.class}, expected a #{@log_record_schema[attr]}" unless [value.class, value.class.superclass].include?(@log_record_schema[attr])
98
111
  end
99
112
  end
100
113
 
101
114
  end
102
- end
115
+ end
@@ -1,3 +1,3 @@
1
1
  module Bellbro
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -1,10 +1,10 @@
1
1
  module Bellbro
2
2
  class Worker
3
- include Shout
4
3
  include Sidekiq::Worker
4
+ include Bellbro::Ringable
5
5
  include Bellbro::Trackable
6
6
  include Bellbro::Hooks
7
- extend Bellbro::SidekiqUtils
7
+ extend Bellbro::SidekiqUtils
8
8
 
9
9
  attr_reader :context
10
10
 
@@ -49,4 +49,4 @@ module Bellbro
49
49
  end
50
50
  end
51
51
  end
52
- end
52
+ end
@@ -2,6 +2,6 @@ logger = Yell.new do |l|
2
2
  l.level = [:debug, :info, :warn, :error]
3
3
  end
4
4
 
5
- Shout::Settings.configure do |config|
5
+ Bellbro::Settings.configure do |config|
6
6
  config.logger = logger
7
- end
7
+ end
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.3.0
4
+ version: 0.3.1
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-03-25 00:00:00.000000000 Z
11
+ date: 2015-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -151,8 +151,11 @@ files:
151
151
  - bellbro.gemspec
152
152
  - lib/bellbro.rb
153
153
  - lib/bellbro/hooks.rb
154
+ - lib/bellbro/ringable.rb
154
155
  - lib/bellbro/service.rb
156
+ - lib/bellbro/settings.rb
155
157
  - lib/bellbro/sidekiq_utils.rb
158
+ - lib/bellbro/timer.rb
156
159
  - lib/bellbro/trackable.rb
157
160
  - lib/bellbro/version.rb
158
161
  - lib/bellbro/worker.rb