sidekiq 6.0.5 → 6.0.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 624626b031eb97839cbef07f74a9e94dee930ef51fb1d471b566be9643b76449
4
- data.tar.gz: 8364d826b034685cbcdb3d46188d88b95add713ec1d3f99998b071aebfe63078
3
+ metadata.gz: 3dd5d7a0dd8a7d877484df4ae3b9988f15e9cc4bc0bb4da23224be0049fa733e
4
+ data.tar.gz: e2b7ddb4c045817837e996356851648bf32108b37fa1abcfb72795a185b4a238
5
5
  SHA512:
6
- metadata.gz: 7375504648039835a884591e972e87c2e3ce2d0a522e6d40c5c2ead886558866f724a5695276214046c1f08a1ad1e19fc65d07670e098aeb126e76b37621b9a5
7
- data.tar.gz: c5af7245e5eee8ad3f0a714306e00e781b770f2ca31afeb6418e8fdd65ac9864bd7dc6fa76880449aa1e3f05623ee60a1d7de266ad06c303ca1e4d96b1f1a52b
6
+ metadata.gz: 5ce3f911b835b38ce212309bcdf81b4789e24a12898a0f2071b9adb9cbcdfa23a33bb7216c2f7c6dcab26d484f79a1271594d3218f63ed041f0027deab5a26f3
7
+ data.tar.gz: 685a6890a43c990b2fd9709c49f9c82c96a487cdcf6fc0607ab15b9dbb47d52c9f797ec5094d3f92ec35c5737e661f966a6b81006ee4b7d99a7f31285180b3db
@@ -58,4 +58,3 @@ workflows:
58
58
  jobs:
59
59
  - "ruby-2.5"
60
60
  - "ruby-2.6"
61
- - "jruby"
data/Changes.md CHANGED
@@ -2,12 +2,33 @@
2
2
 
3
3
  [Sidekiq Changes](https://github.com/mperham/sidekiq/blob/master/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/master/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/master/Ent-Changes.md)
4
4
 
5
+ 6.0.7
6
+ ---------
7
+
8
+ - Refactor systemd integration to work better with custom binaries [#4511]
9
+ - Don't connect to Redis at process exit if not needed [#4502]
10
+ - Remove Redis connection naming [#4479]
11
+ - Fix Redis Sentinel password redaction [#4499]
12
+ - Add Vietnamese locale (vi) [#4528]
13
+
14
+ 6.0.6
15
+ ---------
16
+
17
+ - **Integrate with systemd's watchdog and notification features** [#4488]
18
+ Set `Type=notify` in [sidekiq.service](https://github.com/mperham/sidekiq/blob/4b8a8bd3ae42f6e48ae1fdaf95ed7d7af18ed8bb/examples/systemd/sidekiq.service#L30-L39). The integration works automatically.
19
+ - Use `setTimeout` rather than `setInterval` to avoid thundering herd [#4480]
20
+ - Fix edge case where a job can be pushed without a queue.
21
+ - Flush job stats at exit [#4498]
22
+ - Check RAILS_ENV before RACK_ENV [#4493]
23
+ - Add Lithuanian locale [#4476]
24
+
5
25
  6.0.5
6
26
  ---------
7
27
 
8
28
  - Fix broken Web UI response when using NewRelic and Rack 2.1.2+. [#4440]
9
29
  - Update APIs to use `UNLINK`, not `DEL`. [#4449]
10
30
  - Fix Ruby 2.7 warnings [#4412]
31
+ - Add support for `APP_ENV` [[95fa5d9]](https://github.com/mperham/sidekiq/commit/95fa5d90192148026e52ca2902f1b83c70858ce8)
11
32
 
12
33
  6.0.4
13
34
  ---------
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sidekiq (6.0.5)
4
+ sidekiq (6.0.7)
5
5
  connection_pool (>= 2.2.2)
6
6
  rack (~> 2.0)
7
7
  rack-protection (>= 2.0.0)
@@ -106,7 +106,7 @@ GEM
106
106
  mini_portile2 (~> 2.4.0)
107
107
  nokogiri (1.10.8-java)
108
108
  parallel (1.19.1)
109
- parser (2.7.0.2)
109
+ parser (2.7.0.4)
110
110
  ast (~> 2.4.0)
111
111
  pry (0.12.2)
112
112
  coderay (~> 1.1.0)
@@ -150,10 +150,10 @@ GEM
150
150
  redis (4.1.3)
151
151
  redis-namespace (1.7.0)
152
152
  redis (>= 3.0.4)
153
- rubocop (0.77.0)
153
+ rubocop (0.79.0)
154
154
  jaro_winkler (~> 1.5.1)
155
155
  parallel (~> 1.10)
156
- parser (>= 2.6)
156
+ parser (>= 2.7.0.1)
157
157
  rainbow (>= 2.2.2, < 4.0)
158
158
  ruby-progressbar (~> 1.7)
159
159
  unicode-display_width (>= 1.4.0, < 1.7)
@@ -172,8 +172,8 @@ GEM
172
172
  activesupport (>= 4.0)
173
173
  sprockets (>= 3.0.0)
174
174
  sqlite3 (1.4.2)
175
- standard (0.1.7)
176
- rubocop (~> 0.77.0)
175
+ standard (0.2.1)
176
+ rubocop (~> 0.79.0)
177
177
  rubocop-performance (~> 1.5.1)
178
178
  thor (1.0.1)
179
179
  thread_safe (0.3.6)
@@ -2,7 +2,13 @@
2
2
 
3
3
  [Sidekiq Changes](https://github.com/mperham/sidekiq/blob/master/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/master/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/master/Ent-Changes.md)
4
4
 
5
- Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
5
+ Please see [http://sidekiq.org](http://sidekiq.org) for more details and how to buy.
6
+
7
+ HEAD
8
+ ---------
9
+
10
+ - Update `constantize` for batch callbacks. [#4469]
11
+
6
12
 
7
13
  5.0.1
8
14
  ---------
@@ -6,9 +6,28 @@ $TESTING = false
6
6
 
7
7
  require_relative '../lib/sidekiq/cli'
8
8
 
9
+ def integrate_with_systemd
10
+ return unless ENV["NOTIFY_SOCKET"]
11
+
12
+ Sidekiq.configure_server do |config|
13
+ Sidekiq.logger.info "Enabling systemd notification integration"
14
+ require "sidekiq/sd_notify"
15
+ config.on(:startup) do
16
+ Sidekiq::SdNotify.ready
17
+ end
18
+ config.on(:shutdown) do
19
+ Sidekiq::SdNotify.stopping
20
+ end
21
+ Sidekiq.start_watchdog if Sidekiq::SdNotify.watchdog?
22
+ end
23
+ end
24
+
9
25
  begin
10
26
  cli = Sidekiq::CLI.instance
11
27
  cli.parse
28
+
29
+ integrate_with_systemd
30
+
12
31
  cli.run
13
32
  rescue => e
14
33
  raise e if $DEBUG
@@ -30,16 +30,16 @@ module Sidekiq
30
30
  startup: [],
31
31
  quiet: [],
32
32
  shutdown: [],
33
- heartbeat: [],
33
+ heartbeat: []
34
34
  },
35
35
  dead_max_jobs: 10_000,
36
36
  dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
37
- reloader: proc { |&block| block.call },
37
+ reloader: proc { |&block| block.call }
38
38
  }
39
39
 
40
40
  DEFAULT_WORKER_OPTIONS = {
41
41
  "retry" => true,
42
- "queue" => "default",
42
+ "queue" => "default"
43
43
  }
44
44
 
45
45
  FAKE_INFO = {
@@ -47,7 +47,7 @@ module Sidekiq
47
47
  "uptime_in_days" => "9999",
48
48
  "connected_clients" => "9999",
49
49
  "used_memory_human" => "9P",
50
- "used_memory_peak_human" => "9P",
50
+ "used_memory_peak_human" => "9P"
51
51
  }
52
52
 
53
53
  def self.❨╯°□°❩╯︵┻━┻
@@ -154,7 +154,7 @@ module Sidekiq
154
154
 
155
155
  def self.default_worker_options=(hash)
156
156
  # stringify
157
- @default_worker_options = default_worker_options.merge(Hash[hash.map { |k, v| [k.to_s, v] }])
157
+ @default_worker_options = default_worker_options.merge(hash.transform_keys(&:to_s))
158
158
  end
159
159
 
160
160
  def self.default_worker_options
@@ -105,7 +105,7 @@ module Sidekiq
105
105
 
106
106
  default_queue_latency: default_queue_latency,
107
107
  workers_size: workers_size,
108
- enqueued: enqueued,
108
+ enqueued: enqueued
109
109
  }
110
110
  end
111
111
 
@@ -54,7 +54,7 @@ module Sidekiq
54
54
 
55
55
  logger.info "Running in #{RUBY_DESCRIPTION}"
56
56
  logger.info Sidekiq::LICENSE
57
- logger.info "Upgrade to Sidekiq Pro for more features and support: http://sidekiq.org" unless defined?(::Sidekiq::Pro)
57
+ logger.info "Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org" unless defined?(::Sidekiq::Pro)
58
58
 
59
59
  # touch the connection pool so it is created before we
60
60
  # fire startup and start multithreading.
@@ -163,7 +163,7 @@ module Sidekiq
163
163
  Sidekiq.logger.warn "<no backtrace available>"
164
164
  end
165
165
  end
166
- },
166
+ }
167
167
  }
168
168
  UNHANDLED_SIGNAL_HANDLER = ->(cli) { Sidekiq.logger.info "No signal handler registered, ignoring" }
169
169
  SIGNAL_HANDLERS.default = UNHANDLED_SIGNAL_HANDLER
@@ -185,8 +185,8 @@ module Sidekiq
185
185
  # See #984 for discussion.
186
186
  # APP_ENV is now the preferred ENV term since it is not tech-specific.
187
187
  # Both Sinatra 2.0+ and Sidekiq support this term.
188
- # RACK_ENV and RAILS_ENV are there for legacy support.
189
- @environment = cli_env || ENV["APP_ENV"] || ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
188
+ # RAILS_ENV and RACK_ENV are there for legacy support.
189
+ @environment = cli_env || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
190
190
  end
191
191
 
192
192
  def symbolize_keys_deep!(hash)
@@ -389,3 +389,5 @@ module Sidekiq
389
389
  end
390
390
  end
391
391
  end
392
+
393
+ require "sidekiq/systemd"
@@ -236,6 +236,8 @@ module Sidekiq
236
236
  defaults = defaults.merge(item["wrapped"].get_sidekiq_options) if item["wrapped"].respond_to?("get_sidekiq_options")
237
237
  item = defaults.merge(item)
238
238
 
239
+ raise(ArgumentError, "Job must include a valid queue name") if item["queue"].nil? || item["queue"] == ""
240
+
239
241
  item["class"] = item["class"].to_s
240
242
  item["queue"] = item["queue"].to_s
241
243
  item["jid"] ||= SecureRandom.hex(12)
@@ -39,7 +39,7 @@ module Sidekiq
39
39
  # attribute to expose the underlying thing.
40
40
  h = {
41
41
  class: job_hash["wrapped"] || job_hash["class"],
42
- jid: job_hash["jid"],
42
+ jid: job_hash["jid"]
43
43
  }
44
44
  h[:bid] = job_hash["bid"] if job_hash["bid"]
45
45
  h[:tags] = job_hash["tags"] if job_hash["tags"]
@@ -16,7 +16,7 @@ module Sidekiq
16
16
  proc { Sidekiq::VERSION },
17
17
  proc { |me, data| data["tag"] },
18
18
  proc { |me, data| "[#{Processor::WORKER_STATE.size} of #{data["concurrency"]} busy]" },
19
- proc { |me, data| "stopping" if me.stopping? },
19
+ proc { |me, data| "stopping" if me.stopping? }
20
20
  ]
21
21
 
22
22
  attr_accessor :manager, :poller, :fetcher
@@ -96,6 +96,32 @@ module Sidekiq
96
96
 
97
97
  end
98
98
 
99
+ def self.flush_stats
100
+ fails = Processor::FAILURE.reset
101
+ procd = Processor::PROCESSED.reset
102
+ return if fails + procd == 0
103
+
104
+ nowdate = Time.now.utc.strftime("%Y-%m-%d")
105
+ begin
106
+ Sidekiq.redis do |conn|
107
+ conn.pipelined do
108
+ conn.incrby("stat:processed", procd)
109
+ conn.incrby("stat:processed:#{nowdate}", procd)
110
+ conn.expire("stat:processed:#{nowdate}", STATS_TTL)
111
+
112
+ conn.incrby("stat:failed", fails)
113
+ conn.incrby("stat:failed:#{nowdate}", fails)
114
+ conn.expire("stat:failed:#{nowdate}", STATS_TTL)
115
+ end
116
+ end
117
+ rescue => ex
118
+ # we're exiting the process, things might be shut down so don't
119
+ # try to handle the exception
120
+ Sidekiq.logger.warn("Unable to flush stats: #{ex}")
121
+ end
122
+ end
123
+ at_exit(&method(:flush_stats))
124
+
99
125
  def ❤
100
126
  key = identity
101
127
  fails = procd = 0
@@ -146,7 +172,7 @@ module Sidekiq
146
172
  ::Process.kill(msg, ::Process.pid)
147
173
  rescue => e
148
174
  # ignore all redis/network issues
149
- logger.error("heartbeat: #{e.message}")
175
+ logger.error("heartbeat: #{e}")
150
176
  # don't lose the counts if there was a network issue
151
177
  Processor::PROCESSED.incr(procd)
152
178
  Processor::FAILURE.incr(fails)
@@ -163,7 +189,7 @@ module Sidekiq
163
189
  "concurrency" => @options[:concurrency],
164
190
  "queues" => @options[:queues].uniq,
165
191
  "labels" => @options[:labels],
166
- "identity" => identity,
192
+ "identity" => identity
167
193
  }
168
194
  end
169
195
  end
@@ -23,7 +23,7 @@ module Sidekiq
23
23
  "info" => 1,
24
24
  "warn" => 2,
25
25
  "error" => 3,
26
- "fatal" => 4,
26
+ "fatal" => 4
27
27
  }
28
28
  LEVELS.default_proc = proc do |_, level|
29
29
  Sidekiq.logger.warn("Invalid log level: #{level.inspect}")
@@ -31,23 +31,23 @@ module Sidekiq
31
31
  end
32
32
 
33
33
  def debug?
34
- level >= 0
34
+ level <= 0
35
35
  end
36
36
 
37
37
  def info?
38
- level >= 1
38
+ level <= 1
39
39
  end
40
40
 
41
41
  def warn?
42
- level >= 2
42
+ level <= 2
43
43
  end
44
44
 
45
45
  def error?
46
- level >= 3
46
+ level <= 3
47
47
  end
48
48
 
49
49
  def fatal?
50
- level >= 4
50
+ level <= 4
51
51
  end
52
52
 
53
53
  def local_level
@@ -152,7 +152,7 @@ module Sidekiq
152
152
  pid: ::Process.pid,
153
153
  tid: tid,
154
154
  lvl: severity,
155
- msg: message,
155
+ msg: message
156
156
  }
157
157
  c = ctx
158
158
  hash["ctx"] = c unless c.empty?
@@ -62,7 +62,7 @@ class Sidekiq::Monitor
62
62
  columns = {
63
63
  name: [:ljust, (["name"] + queue_data.map(&:name)).map(&:length).max + COL_PAD],
64
64
  size: [:rjust, (["size"] + queue_data.map(&:size)).map(&:length).max + COL_PAD],
65
- latency: [:rjust, (["latency"] + queue_data.map(&:latency)).map(&:length).max + COL_PAD],
65
+ latency: [:rjust, (["latency"] + queue_data.map(&:latency)).map(&:length).max + COL_PAD]
66
66
  }
67
67
  columns.each { |col, (dir, width)| print col.to_s.upcase.public_send(dir, width) }
68
68
  puts
@@ -101,7 +101,7 @@ class Sidekiq::Monitor
101
101
  tags = [
102
102
  process["tag"],
103
103
  process["labels"],
104
- (process["quiet"] == "true" ? "quiet" : nil),
104
+ (process["quiet"] == "true" ? "quiet" : nil)
105
105
  ].flatten.compact
106
106
  tags.any? ? "[#{tags.join("] [")}]" : nil
107
107
  end
@@ -12,8 +12,9 @@ module Sidekiq
12
12
  options[key.to_sym] = options.delete(key)
13
13
  end
14
14
 
15
- options[:id] = "Sidekiq-#{Sidekiq.server? ? "server" : "client"}-PID-#{::Process.pid}" unless options.key?(:id)
16
- options[:url] ||= determine_redis_provider
15
+ if !options[:url] && (u = determine_redis_provider)
16
+ options[:url] = u
17
+ end
17
18
 
18
19
  size = if options[:size]
19
20
  options[:size]
@@ -93,9 +94,10 @@ module Sidekiq
93
94
  end
94
95
 
95
96
  def log_info(options)
96
- # Don't log Redis AUTH password
97
97
  redacted = "REDACTED"
98
- scrubbed_options = options.dup
98
+
99
+ # deep clone so we can muck with these options all we want
100
+ scrubbed_options = Marshal.load(Marshal.dump(options))
99
101
  if scrubbed_options[:url] && (uri = URI.parse(scrubbed_options[:url])) && uri.password
100
102
  uri.password = redacted
101
103
  scrubbed_options[:url] = uri.to_s
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2017, 2018, 2019, 2020 Agis Anastasopoulos
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
8
+ # this software and associated documentation files (the "Software"), to deal in
9
+ # the Software without restriction, including without limitation the rights to
10
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
+ # the Software, and to permit persons to whom the Software is furnished to do so,
12
+ # subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ # This is a copy of https://github.com/agis/ruby-sdnotify as of commit a7d52ee
25
+ # The only changes made was "rehoming" it within the Sidekiq module to avoid
26
+ # namespace collisions and applying standard's code formatting style.
27
+
28
+ require "socket"
29
+
30
+ # SdNotify is a pure-Ruby implementation of sd_notify(3). It can be used to
31
+ # notify systemd about state changes. Methods of this package are no-op on
32
+ # non-systemd systems (eg. Darwin).
33
+ #
34
+ # The API maps closely to the original implementation of sd_notify(3),
35
+ # therefore be sure to check the official man pages prior to using SdNotify.
36
+ #
37
+ # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html
38
+ module Sidekiq
39
+ module SdNotify
40
+ # Exception raised when there's an error writing to the notification socket
41
+ class NotifyError < RuntimeError; end
42
+
43
+ READY = "READY=1"
44
+ RELOADING = "RELOADING=1"
45
+ STOPPING = "STOPPING=1"
46
+ STATUS = "STATUS="
47
+ ERRNO = "ERRNO="
48
+ MAINPID = "MAINPID="
49
+ WATCHDOG = "WATCHDOG=1"
50
+ FDSTORE = "FDSTORE=1"
51
+
52
+ def self.ready(unset_env = false)
53
+ notify(READY, unset_env)
54
+ end
55
+
56
+ def self.reloading(unset_env = false)
57
+ notify(RELOADING, unset_env)
58
+ end
59
+
60
+ def self.stopping(unset_env = false)
61
+ notify(STOPPING, unset_env)
62
+ end
63
+
64
+ # @param status [String] a custom status string that describes the current
65
+ # state of the service
66
+ def self.status(status, unset_env = false)
67
+ notify("#{STATUS}#{status}", unset_env)
68
+ end
69
+
70
+ # @param errno [Integer]
71
+ def self.errno(errno, unset_env = false)
72
+ notify("#{ERRNO}#{errno}", unset_env)
73
+ end
74
+
75
+ # @param pid [Integer]
76
+ def self.mainpid(pid, unset_env = false)
77
+ notify("#{MAINPID}#{pid}", unset_env)
78
+ end
79
+
80
+ def self.watchdog(unset_env = false)
81
+ notify(WATCHDOG, unset_env)
82
+ end
83
+
84
+ def self.fdstore(unset_env = false)
85
+ notify(FDSTORE, unset_env)
86
+ end
87
+
88
+ # @param [Boolean] true if the service manager expects watchdog keep-alive
89
+ # notification messages to be sent from this process.
90
+ #
91
+ # If the $WATCHDOG_USEC environment variable is set,
92
+ # and the $WATCHDOG_PID variable is unset or set to the PID of the current
93
+ # process
94
+ #
95
+ # @note Unlike sd_watchdog_enabled(3), this method does not mutate the
96
+ # environment.
97
+ def self.watchdog?
98
+ wd_usec = ENV["WATCHDOG_USEC"]
99
+ wd_pid = ENV["WATCHDOG_PID"]
100
+
101
+ return false unless wd_usec
102
+
103
+ begin
104
+ wd_usec = Integer(wd_usec)
105
+ rescue
106
+ return false
107
+ end
108
+
109
+ return false if wd_usec <= 0
110
+ return true if !wd_pid || wd_pid == $$.to_s
111
+
112
+ false
113
+ end
114
+
115
+ # Notify systemd with the provided state, via the notification socket, if
116
+ # any.
117
+ #
118
+ # Generally this method will be used indirectly through the other methods
119
+ # of the library.
120
+ #
121
+ # @param state [String]
122
+ # @param unset_env [Boolean]
123
+ #
124
+ # @return [Fixnum, nil] the number of bytes written to the notification
125
+ # socket or nil if there was no socket to report to (eg. the program wasn't
126
+ # started by systemd)
127
+ #
128
+ # @raise [NotifyError] if there was an error communicating with the systemd
129
+ # socket
130
+ #
131
+ # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html
132
+ def self.notify(state, unset_env = false)
133
+ sock = ENV["NOTIFY_SOCKET"]
134
+
135
+ return nil unless sock
136
+
137
+ ENV.delete("NOTIFY_SOCKET") if unset_env
138
+
139
+ begin
140
+ Addrinfo.unix(sock, :DGRAM).connect do |s|
141
+ s.close_on_exec = true
142
+ s.write(state)
143
+ end
144
+ rescue => e
145
+ raise NotifyError, "#{e.class}: #{e.message}", e.backtrace
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,24 @@
1
+ #
2
+ # Sidekiq's systemd integration allows Sidekiq to inform systemd:
3
+ # 1. when it has successfully started
4
+ # 2. when it is starting shutdown
5
+ # 3. periodically for a liveness check with a watchdog thread
6
+ #
7
+ module Sidekiq
8
+ def self.start_watchdog
9
+ usec = Integer(ENV["WATCHDOG_USEC"])
10
+ return Sidekiq.logger.error("systemd Watchdog too fast: " + usec) if usec < 1_000_000
11
+
12
+ sec_f = usec / 1_000_000.0
13
+ # "It is recommended that a daemon sends a keep-alive notification message
14
+ # to the service manager every half of the time returned here."
15
+ ping_f = sec_f / 2
16
+ Sidekiq.logger.info "Pinging systemd watchdog every #{ping_f.round(1)} sec"
17
+ Thread.new do
18
+ loop do
19
+ sleep ping_f
20
+ Sidekiq::SdNotify.watchdog
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "6.0.5"
4
+ VERSION = "6.0.7"
5
5
  end
@@ -31,7 +31,7 @@ module Sidekiq
31
31
  "Queues" => "queues",
32
32
  "Retries" => "retries",
33
33
  "Scheduled" => "scheduled",
34
- "Dead" => "morgue",
34
+ "Dead" => "morgue"
35
35
  }
36
36
 
37
37
  class << self
@@ -19,7 +19,7 @@ module Sidekiq
19
19
  "script-src 'self' https: http: 'unsafe-inline'",
20
20
  "style-src 'self' https: http: 'unsafe-inline'",
21
21
  "worker-src 'self'",
22
- "base-uri 'self'",
22
+ "base-uri 'self'"
23
23
  ].join("; ").freeze
24
24
 
25
25
  def initialize(klass)
@@ -275,7 +275,7 @@ module Sidekiq
275
275
  scheduled: sidekiq_stats.scheduled_size,
276
276
  retries: sidekiq_stats.retry_size,
277
277
  dead: sidekiq_stats.dead_size,
278
- default_latency: sidekiq_stats.default_queue_latency,
278
+ default_latency: sidekiq_stats.default_queue_latency
279
279
  },
280
280
  redis: redis_stats,
281
281
  server_utc_time: server_utc_time
@@ -308,7 +308,7 @@ module Sidekiq
308
308
  "Content-Type" => "text/html",
309
309
  "Cache-Control" => "no-cache",
310
310
  "Content-Language" => action.locale,
311
- "Content-Security-Policy" => CSP_HEADER,
311
+ "Content-Security-Policy" => CSP_HEADER
312
312
  }
313
313
  # we'll let Rack calculate Content-Length for us.
314
314
  [200, headers, [resp]]
@@ -94,9 +94,7 @@ module Sidekiq
94
94
  {} if path == matcher
95
95
  else
96
96
  path_match = path.match(matcher)
97
- if path_match
98
- Hash[path_match.names.map(&:to_sym).zip(path_match.captures)]
99
- end
97
+ path_match&.named_captures&.transform_keys(&:to_sym)
100
98
  end
101
99
  end
102
100
  end
@@ -48,8 +48,8 @@ module Sidekiq
48
48
  # In practice, any option is allowed. This is the main mechanism to configure the
49
49
  # options for a specific job.
50
50
  def sidekiq_options(opts = {})
51
- opts = Hash[opts.map { |k, v| [k.to_s, v] }] # stringify
52
- self.sidekiq_options_hash = get_sidekiq_options.merge(Hash[opts.map { |k, v| [k.to_s, v] }])
51
+ opts = opts.transform_keys(&:to_s) # stringify
52
+ self.sidekiq_options_hash = get_sidekiq_options.merge(opts)
53
53
  end
54
54
 
55
55
  def sidekiq_retry_in(&block)
@@ -19,7 +19,8 @@ Sidekiq = {};
19
19
  $(function() {
20
20
  var pollpath = $('body').data('poll-path');
21
21
  if (pollpath != "") {
22
- updatePage(pollpath);
22
+ var ti = parseInt(localStorage.timeInterval) || 2000;
23
+ setTimeout(function(){updatePage(pollpath)}, ti);
23
24
  }
24
25
 
25
26
  $(document).on('click', '.check_all', function() {
@@ -55,26 +56,28 @@ function updateFuzzyTimes(locale) {
55
56
  }
56
57
 
57
58
  function updatePage(url) {
58
- setInterval(function () {
59
- $.ajax({
60
- url: url,
61
- dataType: 'html'
62
- }).done(function (data) {
63
- $data = $(data)
64
-
65
- var $page = $data.filter('#page')
66
- $('#page').replaceWith($page)
67
-
68
- var $header_status = $data.find('.status')
69
- $('.status').replaceWith($header_status)
70
-
71
- updateFuzzyTimes($('body').data('locale'));
72
- })
73
- }, parseInt(localStorage.timeInterval) || 2000);
59
+ $.ajax({
60
+ url: url,
61
+ dataType: 'html'
62
+ }).done(function(data) {
63
+ $data = $(data)
64
+
65
+ var $page = $data.filter('#page')
66
+ $('#page').replaceWith($page)
67
+
68
+ var $header_status = $data.find('.status')
69
+ $('.status').replaceWith($header_status)
70
+
71
+ updateFuzzyTimes($('body').data('locale'));
72
+
73
+ var ti = parseInt(localStorage.timeInterval) || 2000;
74
+ setTimeout(function(){updatePage(url)}, ti)
75
+ }).fail(function() {
76
+ var ti = parseInt(localStorage.timeInterval) || 2000;
77
+ setTimeout(function(){updatePage(url)}, ti)
78
+ })
74
79
  }
75
80
 
76
-
77
-
78
81
  $(function() {
79
82
  'use strict';
80
83
 
@@ -1,125 +1,122 @@
1
- @media (prefers-color-scheme: dark) {
2
-
3
- body {
4
- background-color: #000;
5
- color: #ccc;
6
- }
7
-
8
- a,
9
- .title,
10
- .summary_bar ul .count,
11
- .navbar .navbar-brand {
12
- color: #af0014;
13
- }
14
-
15
- .navbar .navbar-brand:hover {
16
- color: #ccc;
17
- }
18
-
19
- .navbar .navbar-brand .status {
20
- color: #ccc;
21
- }
22
-
23
- .navbar-inverse {
24
- background-color: #000;
25
- border-color: #333;
26
- }
27
-
28
- table.table-white {
29
- background-color: #111;
30
- }
31
-
32
- .table-striped > tbody > tr:nth-of-type(odd) {
33
- background-color: #222;
34
- }
35
-
36
- .table-bordered,
37
- .table-bordered > tbody > tr > td,
38
- .table-bordered > tbody > tr > th,
39
- .table-bordered > tfoot > tr > td,
40
- .table-bordered > tfoot > tr > th,
41
- .table-bordered > thead > tr > td,
42
- .table-bordered > thead > tr > th {
43
- border: 1px solid #333;
44
- }
45
-
46
- .table-hover > tbody > tr:hover {
47
- background-color: #333;
48
- }
49
-
50
- .alert {
51
- border: none;
52
- color: #ccc;
53
- }
54
-
55
- .alert-success {
56
- background-color: #000;
57
- }
58
-
59
- a:link,
60
- a:active,
61
- a:hover,
62
- a:visited {
63
- color: #63798c;
64
- }
65
-
66
- a.btn {
67
- color: #000;
68
- }
69
-
70
- .summary_bar .summary {
71
- background-color: #000;
72
- border: 1px solid #333;
73
- }
74
-
75
- .navbar-default {
76
- background-color: #000;
77
- border-color: #3d3d3d;
78
- }
79
-
80
- .navbar-default .navbar-nav > .active > a,
81
- .navbar-default .navbar-nav > .active > a:focus,
82
- .navbar-default .navbar-nav > .active > a:hover {
83
- color: #ccc;
84
- background-color: #282828;
85
- }
86
-
87
- .navbar-default .navbar-nav > li > a:hover {
88
- color: #ccc;
89
- }
90
-
91
- .pagination > li > a,
92
- .pagination > li > a:hover,
93
- .pagination > li > span {
94
- color: #ccc;
95
- background-color: #282828;
96
- border-color: #353535;
97
- }
98
- .pagination > .disabled > a,
99
- .pagination > .disabled > a:focus,
100
- .pagination > .disabled > a:hover,
101
- .pagination > .disabled > span,
102
- .pagination > .disabled > span:focus,
103
- .pagination > .disabled > span:hover {
104
- color: #a5a5a5;
105
- background-color: #282828;
106
- border-color: #353535;
107
- }
108
-
109
- .stat {
110
- border: 1px solid rgba(255, 255, 255, 0.1);
111
- }
112
-
113
- #live-poll {
114
- color: #ccc;
115
- }
116
-
117
- .btn-warn {
118
- color: #333;
119
- }
120
-
121
- .rickshaw_graph .y_ticks.glow text {
122
- fill: #ccc;
123
- color: #ccc;
124
- }
1
+ body {
2
+ background-color: #000;
3
+ color: #ccc;
4
+ }
5
+
6
+ a,
7
+ .title,
8
+ .summary_bar ul .count,
9
+ .navbar .navbar-brand {
10
+ color: #af0014;
11
+ }
12
+
13
+ .navbar .navbar-brand:hover {
14
+ color: #ccc;
15
+ }
16
+
17
+ .navbar .navbar-brand .status {
18
+ color: #ccc;
19
+ }
20
+
21
+ .navbar-inverse {
22
+ background-color: #000;
23
+ border-color: #333;
24
+ }
25
+
26
+ table.table-white {
27
+ background-color: #111;
28
+ }
29
+
30
+ .table-striped > tbody > tr:nth-of-type(odd) {
31
+ background-color: #222;
32
+ }
33
+
34
+ .table-bordered,
35
+ .table-bordered > tbody > tr > td,
36
+ .table-bordered > tbody > tr > th,
37
+ .table-bordered > tfoot > tr > td,
38
+ .table-bordered > tfoot > tr > th,
39
+ .table-bordered > thead > tr > td,
40
+ .table-bordered > thead > tr > th {
41
+ border: 1px solid #333;
42
+ }
43
+
44
+ .table-hover > tbody > tr:hover {
45
+ background-color: #333;
46
+ }
47
+
48
+ .alert {
49
+ border: none;
50
+ color: #ccc;
51
+ }
52
+
53
+ .alert-success {
54
+ background-color: #000;
55
+ }
56
+
57
+ a:link,
58
+ a:active,
59
+ a:hover,
60
+ a:visited {
61
+ color: #63798c;
62
+ }
63
+
64
+ a.btn {
65
+ color: #000;
66
+ }
67
+
68
+ .summary_bar .summary {
69
+ background-color: #000;
70
+ border: 1px solid #333;
71
+ }
72
+
73
+ .navbar-default {
74
+ background-color: #000;
75
+ border-color: #3d3d3d;
76
+ }
77
+
78
+ .navbar-default .navbar-nav > .active > a,
79
+ .navbar-default .navbar-nav > .active > a:focus,
80
+ .navbar-default .navbar-nav > .active > a:hover {
81
+ color: #ccc;
82
+ background-color: #282828;
83
+ }
84
+
85
+ .navbar-default .navbar-nav > li > a:hover {
86
+ color: #ccc;
87
+ }
88
+
89
+ .pagination > li > a,
90
+ .pagination > li > a:hover,
91
+ .pagination > li > span {
92
+ color: #ccc;
93
+ background-color: #282828;
94
+ border-color: #353535;
95
+ }
96
+ .pagination > .disabled > a,
97
+ .pagination > .disabled > a:focus,
98
+ .pagination > .disabled > a:hover,
99
+ .pagination > .disabled > span,
100
+ .pagination > .disabled > span:focus,
101
+ .pagination > .disabled > span:hover {
102
+ color: #a5a5a5;
103
+ background-color: #282828;
104
+ border-color: #353535;
105
+ }
106
+
107
+ .stat {
108
+ border: 1px solid rgba(255, 255, 255, 0.1);
109
+ }
110
+
111
+ #live-poll {
112
+ color: #ccc;
113
+ }
114
+
115
+ .btn-warn {
116
+ color: #333;
117
+ }
118
+
119
+ .rickshaw_graph .y_ticks.glow text {
120
+ fill: #ccc;
121
+ color: #ccc;
125
122
  }
@@ -69,9 +69,9 @@ fr:
69
69
  Jobs: Tâches
70
70
  Paused: Mise en pause
71
71
  Stop: Arrêter
72
- Quiet: Clôturer
72
+ Quiet: Clore
73
73
  StopAll: Tout arrêter
74
- QuietAll: Tout clôturer
74
+ QuietAll: Tout clore
75
75
  PollingInterval: Interval de rafraîchissement
76
76
  Plugins: Plugins
77
77
  NotYetEnqueued: Pas encore en file d'attente
@@ -0,0 +1,83 @@
1
+ # elements like %{queue} are variables and should not be translated
2
+ lt:
3
+ Dashboard: Valdymo skydas
4
+ Status: Būsena
5
+ Time: Laikas
6
+ Namespace: Vardų erdvė
7
+ Realtime: Realiu laiku
8
+ History: Istorija
9
+ Busy: Užimti
10
+ Processed: Įvykdyti
11
+ Failed: Nepavykę
12
+ Scheduled: Suplanuoti
13
+ Retries: Kartojami
14
+ Enqueued: Eilėje
15
+ Worker: Darbuotojas
16
+ LivePoll: Užklausti gyvai
17
+ StopPolling: Stabdyti užklausas
18
+ Queue: Eilė
19
+ Class: Klasė
20
+ Job: Darbas
21
+ Arguments: Parametrai
22
+ Extras: Papildomi
23
+ Started: Pradėti
24
+ ShowAll: Rodyti Visus
25
+ CurrentMessagesInQueue: Esami darbai eilėje <span class='title'>%{queue}</span>
26
+ Delete: Pašalinti
27
+ AddToQueue: Pridėti į eilę
28
+ AreYouSureDeleteJob: Ar tikrai norite pašalinti šį darbą?
29
+ AreYouSureDeleteQueue: Ar tikrai norite pašalinti šią eilę %{queue}?
30
+ Queues: Eilės
31
+ Size: Dydis
32
+ Actions: Veiksmai
33
+ NextRetry: Sekantis Kartojimas
34
+ RetryCount: Kartojimų Skaičius
35
+ RetryNow: Kartoti Dabar
36
+ Kill: Priverstinai Nutraukti
37
+ LastRetry: Paskutinis Kartojimas
38
+ OriginallyFailed: Iš pradžių Nepavykę
39
+ AreYouSure: Ar jūs įsitikinę?
40
+ DeleteAll: Pašalinti Visus
41
+ RetryAll: Kartoti Visus
42
+ KillAll: Priverstinai Nutraukti Visus
43
+ NoRetriesFound: Nerasta kartojimų
44
+ Error: Klaida
45
+ ErrorClass: Klaidos Klasė
46
+ ErrorMessage: Klaidos Žinutė
47
+ ErrorBacktrace: Klaidos Pėdsakai
48
+ GoBack: ← Atgal
49
+ NoScheduledFound: Planuojamų darbų nerasta
50
+ When: Kada
51
+ ScheduledJobs: Planuojami Darbai
52
+ idle: neveiksnus
53
+ active: aktyvus
54
+ Version: Versija
55
+ Connections: Ryšiai
56
+ MemoryUsage: Atminties Vartojimas
57
+ PeakMemoryUsage: Atminties Vartojimo Pikas
58
+ Uptime: Gyvavimo laikas (dienomis)
59
+ OneWeek: 1 savaitė
60
+ OneMonth: 1 mėnuo
61
+ ThreeMonths: 3 mėnesiai
62
+ SixMonths: 6 mėnesiai
63
+ Failures: Nesėkmingi vykdymai
64
+ DeadJobs: Negyvi Darbai
65
+ NoDeadJobsFound: Negyvų darbų nerasta
66
+ Dead: Negyvi
67
+ Processes: Procesai
68
+ Thread: Gija
69
+ Threads: Gijos
70
+ Jobs: Darbai
71
+ Paused: Pristabdytas
72
+ Stop: Sustabdyti
73
+ Quiet: Nutildyti
74
+ StopAll: Sustbadyti Visus
75
+ QuietAll: Nutildyti Visus
76
+ PollingInterval: Užklausimų intervalas
77
+ Plugins: Įskiepiai
78
+ NotYetEnqueued: Dar neįtraukti į eilę
79
+ CreatedAt: Sukurta
80
+ BackToApp: Atgal į Aplikaciją
81
+ Latency: Vėlavimas
82
+ Pause: Pristabdyti
83
+ Unpause: Pratęsti
@@ -0,0 +1,83 @@
1
+ # elements like %{queue} are variables and should not be translated
2
+ vi: # <---- change this to your locale code
3
+ Dashboard: Bảng điều khiển
4
+ Status: Trạng thái
5
+ Time: Thời gian
6
+ Namespace: Không gian tên
7
+ Realtime: Thời gian thực
8
+ History: Lịch sử
9
+ Busy: Bận rộn
10
+ Processed: Đã xử lí
11
+ Failed: Đã thất bại
12
+ Scheduled: Đã lên lịch
13
+ Retries: Số lần thử
14
+ Enqueued: Đã xếp hàng đợi
15
+ Worker: Máy xử lí
16
+ LivePoll: Thăm dò trực tiếp
17
+ StopPolling: Ngừng thăm dò
18
+ Queue: Hàng đợi
19
+ Class: Lớp
20
+ Job: Tác vụ
21
+ Arguments: Tham số
22
+ Extras: Thêm
23
+ Started: Đã bắt đầu
24
+ ShowAll: Hiện tất cả
25
+ CurrentMessagesInQueue: Số lượng công việc trong <span class='title'>%{queue}</span>
26
+ Delete: Xóa
27
+ AddToQueue: Thêm vào hàng đợi
28
+ AreYouSureDeleteJob: Bạn có chắc là muốn xóa tác vụ này?
29
+ AreYouSureDeleteQueue: Bạn có chắc là muốn xóa %{queue} này?
30
+ Queues: Các hàng đợi
31
+ Size: Kích thước
32
+ Actions: Những hành động
33
+ NextRetry: Lần thử lại tiếp theo
34
+ RetryCount: Số lần thử lại
35
+ RetryNow: Thử lại ngay bây giờ
36
+ Kill: Giết
37
+ LastRetry: Lần thử cuối
38
+ OriginallyFailed: Đã thất bại từ đầu
39
+ AreYouSure: Bạn chắc chứ?
40
+ DeleteAll: Xóa hết
41
+ RetryAll: Thử lại tất cả
42
+ KillAll: Giết hết
43
+ NoRetriesFound: Không có lần thử nào được tìm thấy
44
+ Error: Lỗi
45
+ ErrorClass: Lớp lỗi
46
+ ErrorMessage: Tin nhắn lỗi
47
+ ErrorBacktrace: Dấu vết của lỗi
48
+ GoBack: ← Trở lại
49
+ NoScheduledFound: Không có tác vụ đã lên lịch nào được tìm thấy
50
+ When: Khi nào
51
+ ScheduledJobs: Những Tác Vụ Được Hẹn
52
+ idle: Đang chờ
53
+ active: Đang hoạt động
54
+ Version: Phiên bản
55
+ Connections: Các kết nối
56
+ MemoryUsage: Lượng bộ nhớ sử dụng
57
+ PeakMemoryUsage: Lượng bộ nhớ sử dụng đỉnh điểm
58
+ Uptime: Thời gian hệ thống đã online (days)
59
+ OneWeek: 1 tuần
60
+ OneMonth: 1 tháng
61
+ ThreeMonths: 3 tháng
62
+ SixMonths: 6 tháng
63
+ Failures: Các thất bại
64
+ DeadJobs: Những tác vụ đã chết
65
+ NoDeadJobsFound: Không có tác vụ đã chết nào được tìm thấy
66
+ Dead: Chết
67
+ Processes: Tiến trình xử lí
68
+ Thread: Luồng xử lí
69
+ Threads: Những luồng xử lí
70
+ Jobs: Các tác vụ
71
+ Paused: Đã tạm dừng
72
+ Stop: Dừng Lại
73
+ Quiet: Im lặng
74
+ StopAll: Dừng lại tất cả
75
+ QuietAll: Làm cho tất cả im lặng
76
+ PollingInterval: Khoảng thời gian giữa các lần thăm dò
77
+ Plugins: Hệ thống đính kèm
78
+ NotYetEnqueued: Chưa được bỏ vào hàng đợi
79
+ CreatedAt: Được tạo vào lúc
80
+ BackToApp: Trở về ứng dụng
81
+ Latency: Độ trễ
82
+ Pause: Tạm dừng
83
+ Unpause: Hủy tạm dừng
@@ -11,7 +11,7 @@
11
11
  <% end %>
12
12
 
13
13
  <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
14
- <link href="<%= root_path %>stylesheets/application-dark.css" media="screen" rel="stylesheet" type="text/css" />
14
+ <link href="<%= root_path %>stylesheets/application-dark.css" media="screen and (prefers-color-scheme: dark)" rel="stylesheet" type="text/css" />
15
15
  <% if rtl? %>
16
16
  <link href="<%= root_path %>stylesheets/application-rtl.css" media="screen" rel="stylesheet" type="text/css" />
17
17
  <% end %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.5
4
+ version: 6.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-14 00:00:00.000000000 Z
11
+ date: 2020-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -130,6 +130,8 @@ files:
130
130
  - lib/sidekiq/rails.rb
131
131
  - lib/sidekiq/redis_connection.rb
132
132
  - lib/sidekiq/scheduled.rb
133
+ - lib/sidekiq/sd_notify.rb
134
+ - lib/sidekiq/systemd.rb
133
135
  - lib/sidekiq/testing.rb
134
136
  - lib/sidekiq/testing/inline.rb
135
137
  - lib/sidekiq/util.rb
@@ -165,6 +167,7 @@ files:
165
167
  - web/locales/it.yml
166
168
  - web/locales/ja.yml
167
169
  - web/locales/ko.yml
170
+ - web/locales/lt.yml
168
171
  - web/locales/nb.yml
169
172
  - web/locales/nl.yml
170
173
  - web/locales/pl.yml
@@ -175,6 +178,7 @@ files:
175
178
  - web/locales/ta.yml
176
179
  - web/locales/uk.yml
177
180
  - web/locales/ur.yml
181
+ - web/locales/vi.yml
178
182
  - web/locales/zh-cn.yml
179
183
  - web/locales/zh-tw.yml
180
184
  - web/views/_footer.erb