bellbro 0.3.0 → 0.3.1

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: 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