sidekiq_cleaner 5.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +61 -0
  3. data/.github/contributing.md +32 -0
  4. data/.github/issue_template.md +11 -0
  5. data/.gitignore +15 -0
  6. data/.travis.yml +11 -0
  7. data/3.0-Upgrade.md +70 -0
  8. data/4.0-Upgrade.md +53 -0
  9. data/5.0-Upgrade.md +56 -0
  10. data/COMM-LICENSE +97 -0
  11. data/Changes.md +1536 -0
  12. data/Ent-Changes.md +238 -0
  13. data/Gemfile +23 -0
  14. data/LICENSE +9 -0
  15. data/Pro-2.0-Upgrade.md +138 -0
  16. data/Pro-3.0-Upgrade.md +44 -0
  17. data/Pro-4.0-Upgrade.md +35 -0
  18. data/Pro-Changes.md +759 -0
  19. data/README.md +55 -0
  20. data/Rakefile +9 -0
  21. data/bin/sidekiq +18 -0
  22. data/bin/sidekiqctl +20 -0
  23. data/bin/sidekiqload +149 -0
  24. data/cleaner/assets/images/favicon.ico +0 -0
  25. data/cleaner/assets/images/logo.png +0 -0
  26. data/cleaner/assets/images/status.png +0 -0
  27. data/cleaner/assets/javascripts/application.js +172 -0
  28. data/cleaner/assets/javascripts/dashboard.js +315 -0
  29. data/cleaner/assets/stylesheets/application-rtl.css +246 -0
  30. data/cleaner/assets/stylesheets/application.css +1144 -0
  31. data/cleaner/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  32. data/cleaner/assets/stylesheets/bootstrap.css +5 -0
  33. data/cleaner/locales/ar.yml +81 -0
  34. data/cleaner/locales/cs.yml +78 -0
  35. data/cleaner/locales/da.yml +68 -0
  36. data/cleaner/locales/de.yml +69 -0
  37. data/cleaner/locales/el.yml +68 -0
  38. data/cleaner/locales/en.yml +81 -0
  39. data/cleaner/locales/es.yml +70 -0
  40. data/cleaner/locales/fa.yml +80 -0
  41. data/cleaner/locales/fr.yml +78 -0
  42. data/cleaner/locales/he.yml +79 -0
  43. data/cleaner/locales/hi.yml +75 -0
  44. data/cleaner/locales/it.yml +69 -0
  45. data/cleaner/locales/ja.yml +80 -0
  46. data/cleaner/locales/ko.yml +68 -0
  47. data/cleaner/locales/nb.yml +77 -0
  48. data/cleaner/locales/nl.yml +68 -0
  49. data/cleaner/locales/pl.yml +59 -0
  50. data/cleaner/locales/pt-br.yml +68 -0
  51. data/cleaner/locales/pt.yml +67 -0
  52. data/cleaner/locales/ru.yml +78 -0
  53. data/cleaner/locales/sv.yml +68 -0
  54. data/cleaner/locales/ta.yml +75 -0
  55. data/cleaner/locales/uk.yml +76 -0
  56. data/cleaner/locales/ur.yml +80 -0
  57. data/cleaner/locales/zh-cn.yml +68 -0
  58. data/cleaner/locales/zh-tw.yml +68 -0
  59. data/cleaner/views/_footer.erb +20 -0
  60. data/cleaner/views/_job_info.erb +88 -0
  61. data/cleaner/views/_nav.erb +52 -0
  62. data/cleaner/views/_paging.erb +23 -0
  63. data/cleaner/views/_poll_link.erb +7 -0
  64. data/cleaner/views/_status.erb +4 -0
  65. data/cleaner/views/_summary.erb +40 -0
  66. data/cleaner/views/busy.erb +98 -0
  67. data/cleaner/views/dashboard.erb +75 -0
  68. data/cleaner/views/dead.erb +34 -0
  69. data/cleaner/views/errors.erb +84 -0
  70. data/cleaner/views/layout.erb +40 -0
  71. data/cleaner/views/morgue.erb +75 -0
  72. data/cleaner/views/queue.erb +46 -0
  73. data/cleaner/views/queues.erb +30 -0
  74. data/cleaner/views/retries.erb +80 -0
  75. data/cleaner/views/retry.erb +34 -0
  76. data/cleaner/views/scheduled.erb +54 -0
  77. data/cleaner/views/scheduled_job_info.erb +8 -0
  78. data/cleaner-stats.png +0 -0
  79. data/cleaner.png +0 -0
  80. data/code_of_conduct.md +50 -0
  81. data/lib/generators/sidekiq/templates/worker.rb.erb +9 -0
  82. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +6 -0
  83. data/lib/generators/sidekiq/templates/worker_test.rb.erb +8 -0
  84. data/lib/generators/sidekiq/worker_generator.rb +49 -0
  85. data/lib/sidekiq/api.rb +940 -0
  86. data/lib/sidekiq/cleaner/action.rb +89 -0
  87. data/lib/sidekiq/cleaner/application.rb +385 -0
  88. data/lib/sidekiq/cleaner/helpers.rb +325 -0
  89. data/lib/sidekiq/cleaner/router.rb +100 -0
  90. data/lib/sidekiq/cleaner.rb +214 -0
  91. data/lib/sidekiq/cli.rb +445 -0
  92. data/lib/sidekiq/client.rb +243 -0
  93. data/lib/sidekiq/core_ext.rb +1 -0
  94. data/lib/sidekiq/ctl.rb +221 -0
  95. data/lib/sidekiq/delay.rb +42 -0
  96. data/lib/sidekiq/exception_handler.rb +29 -0
  97. data/lib/sidekiq/extensions/action_mailer.rb +57 -0
  98. data/lib/sidekiq/extensions/active_record.rb +40 -0
  99. data/lib/sidekiq/extensions/class_methods.rb +40 -0
  100. data/lib/sidekiq/extensions/generic_proxy.rb +31 -0
  101. data/lib/sidekiq/fetch.rb +81 -0
  102. data/lib/sidekiq/job_logger.rb +25 -0
  103. data/lib/sidekiq/job_retry.rb +262 -0
  104. data/lib/sidekiq/launcher.rb +173 -0
  105. data/lib/sidekiq/logging.rb +122 -0
  106. data/lib/sidekiq/manager.rb +137 -0
  107. data/lib/sidekiq/middleware/chain.rb +150 -0
  108. data/lib/sidekiq/middleware/i18n.rb +42 -0
  109. data/lib/sidekiq/middleware/server/active_record.rb +23 -0
  110. data/lib/sidekiq/paginator.rb +43 -0
  111. data/lib/sidekiq/processor.rb +279 -0
  112. data/lib/sidekiq/rails.rb +58 -0
  113. data/lib/sidekiq/redis_connection.rb +144 -0
  114. data/lib/sidekiq/scheduled.rb +174 -0
  115. data/lib/sidekiq/testing/inline.rb +29 -0
  116. data/lib/sidekiq/testing.rb +333 -0
  117. data/lib/sidekiq/util.rb +66 -0
  118. data/lib/sidekiq/version.rb +4 -0
  119. data/lib/sidekiq/worker.rb +220 -0
  120. data/lib/sidekiq.rb +237 -0
  121. data/sidekiq_cleaner.gemspec +21 -0
  122. metadata +235 -0
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ require 'socket'
3
+ require 'securerandom'
4
+ require 'sidekiq/exception_handler'
5
+
6
+ module Sidekiq
7
+ ##
8
+ # This module is part of Sidekiq core and not intended for extensions.
9
+ #
10
+ module Util
11
+ include ExceptionHandler
12
+
13
+ EXPIRY = 60 * 60 * 24
14
+
15
+ def watchdog(last_words)
16
+ yield
17
+ rescue Exception => ex
18
+ handle_exception(ex, { context: last_words })
19
+ raise ex
20
+ end
21
+
22
+ def safe_thread(name, &block)
23
+ Thread.new do
24
+ Thread.current['sidekiq_label'] = name
25
+ watchdog(name, &block)
26
+ end
27
+ end
28
+
29
+ def logger
30
+ Sidekiq.logger
31
+ end
32
+
33
+ def redis(&block)
34
+ Sidekiq.redis(&block)
35
+ end
36
+
37
+ def hostname
38
+ ENV['DYNO'] || Socket.gethostname
39
+ end
40
+
41
+ def process_nonce
42
+ @@process_nonce ||= SecureRandom.hex(6)
43
+ end
44
+
45
+ def identity
46
+ @@identity ||= "#{hostname}:#{$$}:#{process_nonce}"
47
+ end
48
+
49
+ def fire_event(event, options={})
50
+ reverse = options[:reverse]
51
+ reraise = options[:reraise]
52
+
53
+ arr = Sidekiq.options[:lifecycle_events][event]
54
+ arr.reverse! if reverse
55
+ arr.each do |block|
56
+ begin
57
+ block.call
58
+ rescue => ex
59
+ handle_exception(ex, { context: "Exception during Sidekiq lifecycle event.", event: event })
60
+ raise ex if reraise
61
+ end
62
+ end
63
+ arr.clear
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ module Sidekiq
3
+ VERSION = "5.3.6"
4
+ end
@@ -0,0 +1,220 @@
1
+ # frozen_string_literal: true
2
+ require 'sidekiq/client'
3
+
4
+ module Sidekiq
5
+
6
+ ##
7
+ # Include this module in your worker class and you can easily create
8
+ # asynchronous jobs:
9
+ #
10
+ # class HardWorker
11
+ # include Sidekiq::Worker
12
+ #
13
+ # def perform(*args)
14
+ # # do some work
15
+ # end
16
+ # end
17
+ #
18
+ # Then in your Rails app, you can do this:
19
+ #
20
+ # HardWorker.perform_async(1, 2, 3)
21
+ #
22
+ # Note that perform_async is a class method, perform is an instance method.
23
+ module Worker
24
+ attr_accessor :jid
25
+
26
+ def self.included(base)
27
+ raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? {|c| c.name == 'ActiveJob::Base' }
28
+
29
+ base.extend(ClassMethods)
30
+ base.sidekiq_class_attribute :sidekiq_options_hash
31
+ base.sidekiq_class_attribute :sidekiq_retry_in_block
32
+ base.sidekiq_class_attribute :sidekiq_retries_exhausted_block
33
+ end
34
+
35
+ def logger
36
+ Sidekiq.logger
37
+ end
38
+
39
+ # This helper class encapsulates the set options for `set`, e.g.
40
+ #
41
+ # SomeWorker.set(queue: 'foo').perform_async(....)
42
+ #
43
+ class Setter
44
+ def initialize(klass, opts)
45
+ @klass = klass
46
+ @opts = opts
47
+ end
48
+
49
+ def set(options)
50
+ @opts.merge!(options)
51
+ self
52
+ end
53
+
54
+ def perform_async(*args)
55
+ @klass.client_push(@opts.merge('args' => args, 'class' => @klass))
56
+ end
57
+
58
+ # +interval+ must be a timestamp, numeric or something that acts
59
+ # numeric (like an activesupport time interval).
60
+ def perform_in(interval, *args)
61
+ int = interval.to_f
62
+ now = Time.now.to_f
63
+ ts = (int < 1_000_000_000 ? now + int : int)
64
+
65
+ payload = @opts.merge('class' => @klass, 'args' => args, 'at' => ts)
66
+ # Optimization to enqueue something now that is scheduled to go out now or in the past
67
+ payload.delete('at') if ts <= now
68
+ @klass.client_push(payload)
69
+ end
70
+ alias_method :perform_at, :perform_in
71
+ end
72
+
73
+ module ClassMethods
74
+ ACCESSOR_MUTEX = Mutex.new
75
+
76
+ def delay(*args)
77
+ raise ArgumentError, "Do not call .delay on a Sidekiq::Worker class, call .perform_async"
78
+ end
79
+
80
+ def delay_for(*args)
81
+ raise ArgumentError, "Do not call .delay_for on a Sidekiq::Worker class, call .perform_in"
82
+ end
83
+
84
+ def delay_until(*args)
85
+ raise ArgumentError, "Do not call .delay_until on a Sidekiq::Worker class, call .perform_at"
86
+ end
87
+
88
+ def set(options)
89
+ Setter.new(self, options)
90
+ end
91
+
92
+ def perform_async(*args)
93
+ client_push('class' => self, 'args' => args)
94
+ end
95
+
96
+ # +interval+ must be a timestamp, numeric or something that acts
97
+ # numeric (like an activesupport time interval).
98
+ def perform_in(interval, *args)
99
+ int = interval.to_f
100
+ now = Time.now.to_f
101
+ ts = (int < 1_000_000_000 ? now + int : int)
102
+
103
+ item = { 'class' => self, 'args' => args, 'at' => ts }
104
+
105
+ # Optimization to enqueue something now that is scheduled to go out now or in the past
106
+ item.delete('at') if ts <= now
107
+
108
+ client_push(item)
109
+ end
110
+ alias_method :perform_at, :perform_in
111
+
112
+ ##
113
+ # Allows customization for this type of Worker.
114
+ # Legal options:
115
+ #
116
+ # queue - use a named queue for this Worker, default 'default'
117
+ # retry - enable the RetryJobs middleware for this Worker, *true* to use the default
118
+ # or *Integer* count
119
+ # backtrace - whether to save any error backtrace in the retry payload to display in web UI,
120
+ # can be true, false or an integer number of lines to save, default *false*
121
+ # pool - use the given Redis connection pool to push this type of job to a given shard.
122
+ #
123
+ # In practice, any option is allowed. This is the main mechanism to configure the
124
+ # options for a specific job.
125
+ def sidekiq_options(opts={})
126
+ # stringify
127
+ self.sidekiq_options_hash = get_sidekiq_options.merge(Hash[opts.map{|k, v| [k.to_s, v]}])
128
+ end
129
+
130
+ def sidekiq_retry_in(&block)
131
+ self.sidekiq_retry_in_block = block
132
+ end
133
+
134
+ def sidekiq_retries_exhausted(&block)
135
+ self.sidekiq_retries_exhausted_block = block
136
+ end
137
+
138
+ def get_sidekiq_options # :nodoc:
139
+ self.sidekiq_options_hash ||= Sidekiq.default_worker_options
140
+ end
141
+
142
+ def client_push(item) # :nodoc:
143
+ pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options['pool'] || Sidekiq.redis_pool
144
+ # stringify
145
+ item.keys.each do |key|
146
+ item[key.to_s] = item.delete(key)
147
+ end
148
+
149
+ Sidekiq::Client.new(pool).push(item)
150
+ end
151
+
152
+ def sidekiq_class_attribute(*attrs)
153
+ instance_reader = true
154
+ instance_writer = true
155
+
156
+ attrs.each do |name|
157
+ synchronized_getter = "__synchronized_#{name}"
158
+
159
+ singleton_class.instance_eval do
160
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
161
+ end
162
+
163
+ define_singleton_method(synchronized_getter) { nil }
164
+ singleton_class.class_eval do
165
+ private(synchronized_getter)
166
+ end
167
+
168
+ define_singleton_method(name) { ACCESSOR_MUTEX.synchronize { send synchronized_getter } }
169
+
170
+ ivar = "@#{name}"
171
+
172
+ singleton_class.instance_eval do
173
+ m = "#{name}="
174
+ undef_method(m) if method_defined?(m) || private_method_defined?(m)
175
+ end
176
+ define_singleton_method("#{name}=") do |val|
177
+ singleton_class.class_eval do
178
+ ACCESSOR_MUTEX.synchronize do
179
+ undef_method(synchronized_getter) if method_defined?(synchronized_getter) || private_method_defined?(synchronized_getter)
180
+ define_method(synchronized_getter) { val }
181
+ end
182
+ end
183
+
184
+ if singleton_class?
185
+ class_eval do
186
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
187
+ define_method(name) do
188
+ if instance_variable_defined? ivar
189
+ instance_variable_get ivar
190
+ else
191
+ singleton_class.send name
192
+ end
193
+ end
194
+ end
195
+ end
196
+ val
197
+ end
198
+
199
+ if instance_reader
200
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
201
+ define_method(name) do
202
+ if instance_variable_defined?(ivar)
203
+ instance_variable_get ivar
204
+ else
205
+ self.class.public_send name
206
+ end
207
+ end
208
+ end
209
+
210
+ if instance_writer
211
+ m = "#{name}="
212
+ undef_method(m) if method_defined?(m) || private_method_defined?(m)
213
+ attr_writer name
214
+ end
215
+ end
216
+ end
217
+
218
+ end
219
+ end
220
+ end
data/lib/sidekiq.rb ADDED
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sidekiq/version'
4
+ fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
5
+
6
+ require 'sidekiq/logging'
7
+ require 'sidekiq/client'
8
+ require 'sidekiq/worker'
9
+ require 'sidekiq/redis_connection'
10
+ require 'sidekiq/delay'
11
+
12
+ require 'json'
13
+
14
+ module Sidekiq
15
+ NAME = 'Sidekiq'
16
+ LICENSE = 'See LICENSE and the LGPL-3.0 for licensing details.'
17
+
18
+ DEFAULTS = {
19
+ queues: [],
20
+ labels: [],
21
+ concurrency: 10,
22
+ require: '.',
23
+ environment: nil,
24
+ timeout: 8,
25
+ poll_interval_average: nil,
26
+ average_scheduled_poll_interval: 5,
27
+ error_handlers: [],
28
+ death_handlers: [],
29
+ lifecycle_events: {
30
+ startup: [],
31
+ quiet: [],
32
+ shutdown: [],
33
+ heartbeat: [],
34
+ },
35
+ dead_max_jobs: 10_000,
36
+ dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
37
+ reloader: proc { |&block| block.call },
38
+ }
39
+
40
+ DEFAULT_WORKER_OPTIONS = {
41
+ 'retry' => true,
42
+ 'queue' => 'default'
43
+ }
44
+
45
+ FAKE_INFO = {
46
+ "redis_version" => "9.9.9",
47
+ "uptime_in_days" => "9999",
48
+ "connected_clients" => "9999",
49
+ "used_memory_human" => "9P",
50
+ "used_memory_peak_human" => "9P"
51
+ }
52
+
53
+ def self.❨╯°□°❩╯︵┻━┻
54
+ puts "Calm down, yo."
55
+ end
56
+
57
+ def self.options
58
+ @options ||= DEFAULTS.dup
59
+ end
60
+
61
+ def self.options=(opts)
62
+ @options = opts
63
+ end
64
+
65
+ ##
66
+ # Configuration for Sidekiq server, use like:
67
+ #
68
+ # Sidekiq.configure_server do |config|
69
+ # config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
70
+ # config.server_middleware do |chain|
71
+ # chain.add MyServerHook
72
+ # end
73
+ # end
74
+ def self.configure_server
75
+ yield self if server?
76
+ end
77
+
78
+ ##
79
+ # Configuration for Sidekiq client, use like:
80
+ #
81
+ # Sidekiq.configure_client do |config|
82
+ # config.redis = { :namespace => 'myapp', :size => 1, :url => 'redis://myhost:8877/0' }
83
+ # end
84
+ def self.configure_client
85
+ yield self unless server?
86
+ end
87
+
88
+ def self.server?
89
+ defined?(Sidekiq::CLI)
90
+ end
91
+
92
+ def self.redis
93
+ raise ArgumentError, "requires a block" unless block_given?
94
+ redis_pool.with do |conn|
95
+ retryable = true
96
+ begin
97
+ yield conn
98
+ rescue Redis::CommandError => ex
99
+ #2550 Failover can cause the server to become a replica, need
100
+ # to disconnect and reopen the socket to get back to the primary.
101
+ (conn.disconnect!; retryable = false; retry) if retryable && ex.message =~ /READONLY/
102
+ raise
103
+ end
104
+ end
105
+ end
106
+
107
+ def self.redis_info
108
+ redis do |conn|
109
+ begin
110
+ # admin commands can't go through redis-namespace starting
111
+ # in redis-namespace 2.0
112
+ if conn.respond_to?(:namespace)
113
+ conn.redis.info
114
+ else
115
+ conn.info
116
+ end
117
+ rescue Redis::CommandError => ex
118
+ #2850 return fake version when INFO command has (probably) been renamed
119
+ raise unless ex.message =~ /unknown command/
120
+ FAKE_INFO
121
+ end
122
+ end
123
+ end
124
+
125
+ def self.redis_pool
126
+ @redis ||= Sidekiq::RedisConnection.create
127
+ end
128
+
129
+ def self.redis=(hash)
130
+ @redis = if hash.is_a?(ConnectionPool)
131
+ hash
132
+ else
133
+ Sidekiq::RedisConnection.create(hash)
134
+ end
135
+ end
136
+
137
+ def self.client_middleware
138
+ @client_chain ||= Middleware::Chain.new
139
+ yield @client_chain if block_given?
140
+ @client_chain
141
+ end
142
+
143
+ def self.server_middleware
144
+ @server_chain ||= default_server_middleware
145
+ yield @server_chain if block_given?
146
+ @server_chain
147
+ end
148
+
149
+ def self.default_server_middleware
150
+ Middleware::Chain.new
151
+ end
152
+
153
+ def self.default_worker_options=(hash)
154
+ # stringify
155
+ @default_worker_options = default_worker_options.merge(Hash[hash.map{|k, v| [k.to_s, v]}])
156
+ end
157
+ def self.default_worker_options
158
+ defined?(@default_worker_options) ? @default_worker_options : DEFAULT_WORKER_OPTIONS
159
+ end
160
+
161
+ def self.default_retries_exhausted=(prok)
162
+ logger.info { "default_retries_exhausted is deprecated, please use `config.death_handlers << -> {|job, ex| }`" }
163
+ return nil unless prok
164
+ death_handlers << prok
165
+ end
166
+
167
+ ##
168
+ # Death handlers are called when all retries for a job have been exhausted and
169
+ # the job dies. It's the notification to your application
170
+ # that this job will not succeed without manual intervention.
171
+ #
172
+ # Sidekiq.configure_server do |config|
173
+ # config.death_handlers << ->(job, ex) do
174
+ # end
175
+ # end
176
+ def self.death_handlers
177
+ options[:death_handlers]
178
+ end
179
+
180
+ def self.load_json(string)
181
+ JSON.parse(string)
182
+ end
183
+ def self.dump_json(object)
184
+ JSON.generate(object)
185
+ end
186
+
187
+ def self.logger
188
+ Sidekiq::Logging.logger
189
+ end
190
+ def self.logger=(log)
191
+ Sidekiq::Logging.logger = log
192
+ end
193
+
194
+ # How frequently Redis should be checked by a random Sidekiq process for
195
+ # scheduled and retriable jobs. Each individual process will take turns by
196
+ # waiting some multiple of this value.
197
+ #
198
+ # See sidekiq/scheduled.rb for an in-depth explanation of this value
199
+ def self.average_scheduled_poll_interval=(interval)
200
+ self.options[:average_scheduled_poll_interval] = interval
201
+ end
202
+
203
+ # Register a proc to handle any error which occurs within the Sidekiq process.
204
+ #
205
+ # Sidekiq.configure_server do |config|
206
+ # config.error_handlers << proc {|ex,ctx_hash| MyErrorService.notify(ex, ctx_hash) }
207
+ # end
208
+ #
209
+ # The default error handler logs errors to Sidekiq.logger.
210
+ def self.error_handlers
211
+ self.options[:error_handlers]
212
+ end
213
+
214
+ # Register a block to run at a point in the Sidekiq lifecycle.
215
+ # :startup, :quiet or :shutdown are valid events.
216
+ #
217
+ # Sidekiq.configure_server do |config|
218
+ # config.on(:shutdown) do
219
+ # puts "Goodbye cruel world!"
220
+ # end
221
+ # end
222
+ def self.on(event, &block)
223
+ raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
224
+ raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
225
+ options[:lifecycle_events][event] << block
226
+ end
227
+
228
+ # We are shutting down Sidekiq but what about workers that
229
+ # are working on some long job? This error is
230
+ # raised in workers that have not finished within the hard
231
+ # timeout limit. This is needed to rollback db transactions,
232
+ # otherwise Ruby's Thread#kill will commit. See #377.
233
+ # DO NOT RESCUE THIS ERROR IN YOUR WORKERS
234
+ class Shutdown < Interrupt; end
235
+ end
236
+
237
+ require 'sidekiq/rails' if defined?(::Rails::Engine)
@@ -0,0 +1,21 @@
1
+ require_relative 'lib/sidekiq/version'
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["Dan Belling"]
5
+ gem.email = ["danhbelling@gmail.com"]
6
+ gem.summary = "A sidekiq cleaner library."
7
+ gem.description = "A cleaner library for the sidekiq job processor for use by the RL engineering team."
8
+ gem.homepage = "https://github.com/reachlocal/sidekiq-cleaner"
9
+ gem.license = "LGPL-3.0"
10
+
11
+ gem.executables = ['sidekiq', 'sidekiqctl']
12
+ gem.files = `git ls-files | grep -Ev '^(test|myapp|examples)'`.split("\n")
13
+ gem.name = "sidekiq_cleaner"
14
+ gem.version = Sidekiq::VERSION
15
+ gem.required_ruby_version = ">= 2.2.2"
16
+
17
+ gem.add_dependency 'redis', '>= 3.3.5', '< 5'
18
+ gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.2'
19
+ gem.add_dependency 'rack', '>= 1.5.0'
20
+ gem.add_dependency 'rack-protection', '>= 1.5.0'
21
+ end