sidekiq 7.0.8 → 7.1.0

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: 69b692f7976998a1655a5c6f108c0a1f686fdcdcde164f6cde071f9ea3f89ced
4
- data.tar.gz: d78d581fa48b744789b3af117a55d71bab1037b592f58ee9c74cf2c132716e0c
3
+ metadata.gz: e35d1e6eac7b96128e63d16ffaa1e1b435edd2d1af2e9ba9eb41e7b548ecafdd
4
+ data.tar.gz: 24717c4bdef48d83ee1467f97a216f023937b2a69a5db726614b78ea054a9699
5
5
  SHA512:
6
- metadata.gz: 42d16710f20a67a94df6498cf1fb5097a8795a5611f058e58d60e43e82503d26871c6d3061b3404590a0e0eba319997cb7e1daec3a88b66c2356e9cc0164a781
7
- data.tar.gz: 5b6d9aa7512a67cb552c3a1bed37aa111a877927e7690f53efd3e85aa1ea7049fb75eb05b31232810c8a805f95cb0959a54cc80bafb5c80f9aae0c0701d158b7
6
+ metadata.gz: 70d4e5e58853a86ee8761c6c766daac03333fd7752c4102db8caca0e1631d7d37377acb3fe2e616497d02e067fbee2577ccdf0b5497cb95ae0ce5414232bac25
7
+ data.tar.gz: 628c9516bd22b09e2b431f917f3218200c137dd36534e9742c41b916e3994b609aecf119e9e0c8caf359ad8b30b2a95974d507e6e99a6e330f5651a4af4142ab
data/Changes.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  [Sidekiq Changes](https://github.com/sidekiq/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/sidekiq/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/sidekiq/sidekiq/blob/main/Ent-Changes.md)
4
4
 
5
+ 7.1.0
6
+ ----------
7
+
8
+ - Improve display of ActiveJob arguments in Web UI [#5825, cover]
9
+ - Update `push_bulk` to push `batch_size` jobs at a time and allow laziness [#5827, fatkodima]
10
+ This allows Sidekiq::Client to push unlimited jobs as long as it has enough memory for the batch_size.
11
+ - Update `perform_bulk` to use `push_bulk` internally.
12
+ - Change return value of `push_bulk` to map 1-to-1 with arguments.
13
+ If you call `push_bulk(args: [[1], [2], [3]])`, you will now always get
14
+ an array of 3 values as the result: `["jid1", nil, "jid3"]` where nil means
15
+ that particular job did not push successfully (possibly due to middleware
16
+ stopping it). Previously nil values were removed so it was impossible to tell
17
+ which jobs pushed successfully and which did not.
18
+ - Migrate away from all deprecated Redis commands [#5788]
19
+ Sidekiq will now print a warning if you use one of those deprecated commands.
20
+ - Prefix all Sidekiq thread names [#5872]
21
+
22
+ 7.0.9
23
+ ----------
24
+
25
+ - Restore confirmation dialogs in Web UI [#5881, shevaun]
26
+ - Increase fetch timeout to minimize ReadTimeoutError [#5874]
27
+ - Reverse histogram tooltip ordering [#5868]
28
+ - Add Scottish Gaelic (gd) locale [#5867, GunChleoc]
29
+
5
30
  7.0.8
6
31
  ----------
7
32
 
data/bin/sidekiqload CHANGED
@@ -1,5 +1,23 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ #
4
+ # bin/sidekiqload is a helpful script to load test and
5
+ # performance tune Sidekiq's core. It creates 500,000 no-op
6
+ # jobs and executes them as fast as possible.
7
+ # Example Usage:
8
+ #
9
+ # > RUBY_YJIT_ENABLE=1 LATENCY=0 THREADS=10 bin/sidekiqload
10
+ # Result: Done, 500000 jobs in 20.264945 sec, 24673 jobs/sec
11
+ #
12
+ # Use LATENCY=1 to get a more real world network setup
13
+ # but you'll need to setup and start toxiproxy as noted below.
14
+ #
15
+ # Use AJ=1 to test ActiveJob instead of plain old Sidekiq::Jobs so
16
+ # you can see the runtime performance difference between the two APIs.
17
+ #
18
+ # None of this script is considered a public API and may change over time.
19
+ #
20
+
3
21
  # Quiet some warnings we see when running in warning mode:
4
22
  # RUBYOPT=-w bundle exec sidekiq
5
23
  $TESTING = false
@@ -32,7 +50,7 @@ if ENV["AJ"]
32
50
  ActiveJob::Base.logger.level = Logger::WARN
33
51
 
34
52
  class LoadJob < ActiveJob::Base
35
- def perform(idx, ts=nil)
53
+ def perform(idx, ts = nil)
36
54
  puts(Time.now.to_f - ts) if !ts.nil?
37
55
  end
38
56
  end
@@ -219,11 +237,11 @@ end
219
237
  ll = Loader.new
220
238
  ll.configure
221
239
 
222
- unless ENV["GC"] || ENV["PROFILE"]
240
+ if ENV["WARM"]
223
241
  ll.setup
224
242
  ll.run("warmup")
225
243
  end
226
244
 
227
245
  ll.setup
228
- ll.run("ideal")
246
+ ll.run("load")
229
247
  ll.done
data/lib/sidekiq/api.rb CHANGED
@@ -391,13 +391,13 @@ module Sidekiq
391
391
  def display_args
392
392
  # Unwrap known wrappers so they show up in a human-friendly manner in the Web UI
393
393
  @display_args ||= if klass == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
394
- job_args = self["wrapped"] ? args[0]["arguments"] : []
394
+ job_args = self["wrapped"] ? deserialize_argument(args[0]["arguments"]) : []
395
395
  if (self["wrapped"] || args[0]) == "ActionMailer::DeliveryJob"
396
396
  # remove MailerClass, mailer_method and 'deliver_now'
397
397
  job_args.drop(3)
398
398
  elsif (self["wrapped"] || args[0]) == "ActionMailer::MailDeliveryJob"
399
399
  # remove MailerClass, mailer_method and 'deliver_now'
400
- job_args.drop(3).first["args"]
400
+ job_args.drop(3).first.values_at("params", "args")
401
401
  else
402
402
  job_args
403
403
  end
@@ -467,6 +467,29 @@ module Sidekiq
467
467
 
468
468
  private
469
469
 
470
+ ACTIVE_JOB_PREFIX = "_aj_"
471
+ GLOBALID_KEY = "_aj_globalid"
472
+
473
+ def deserialize_argument(argument)
474
+ case argument
475
+ when Array
476
+ argument.map { |arg| deserialize_argument(arg) }
477
+ when Hash
478
+ if serialized_global_id?(argument)
479
+ argument[GLOBALID_KEY]
480
+ else
481
+ argument.transform_values { |v| deserialize_argument(v) }
482
+ .reject { |k, _| k.start_with?(ACTIVE_JOB_PREFIX) }
483
+ end
484
+ else
485
+ argument
486
+ end
487
+ end
488
+
489
+ def serialized_global_id?(hash)
490
+ hash.size == 1 && hash.include?(GLOBALID_KEY)
491
+ end
492
+
470
493
  def uncompress_backtrace(backtrace)
471
494
  decoded = Base64.decode64(backtrace)
472
495
  uncompressed = Zlib::Inflate.inflate(decoded)
@@ -548,7 +571,7 @@ module Sidekiq
548
571
  def remove_job
549
572
  Sidekiq.redis do |conn|
550
573
  results = conn.multi { |transaction|
551
- transaction.zrangebyscore(parent.name, score, score)
574
+ transaction.zrange(parent.name, score, score, "BYSCORE")
552
575
  transaction.zremrangebyscore(parent.name, score, score)
553
576
  }.first
554
577
 
@@ -683,7 +706,7 @@ module Sidekiq
683
706
  end
684
707
 
685
708
  elements = Sidekiq.redis { |conn|
686
- conn.zrangebyscore(name, begin_score, end_score, withscores: true)
709
+ conn.zrange(name, begin_score, end_score, "BYSCORE", withscores: true)
687
710
  }
688
711
 
689
712
  elements.each_with_object([]) do |element, result|
@@ -724,7 +747,7 @@ module Sidekiq
724
747
  # @api private
725
748
  def delete_by_jid(score, jid)
726
749
  Sidekiq.redis do |conn|
727
- elements = conn.zrangebyscore(name, score, score)
750
+ elements = conn.zrange(name, score, score, "BYSCORE")
728
751
  elements.each do |element|
729
752
  if element.index(jid)
730
753
  message = Sidekiq.load_json(element)
data/lib/sidekiq/cli.rb CHANGED
@@ -396,7 +396,7 @@ module Sidekiq # :nodoc:
396
396
  end
397
397
 
398
398
  def parse_config(path)
399
- erb = ERB.new(File.read(path))
399
+ erb = ERB.new(File.read(path), trim_mode: "-")
400
400
  erb.filename = File.expand_path(path)
401
401
  opts = YAML.safe_load(erb.result, permitted_classes: [Symbol], aliases: true) || {}
402
402
 
@@ -96,8 +96,9 @@ module Sidekiq
96
96
 
97
97
  ##
98
98
  # Push a large number of jobs to Redis. This method cuts out the redis
99
- # network round trip latency. I wouldn't recommend pushing more than
100
- # 1000 per call but YMMV based on network quality, size of job args, etc.
99
+ # network round trip latency. It pushes jobs in batches if more than
100
+ # `:batch_size` (1000 by default) of jobs are passed. I wouldn't recommend making `:batch_size`
101
+ # larger than 1000 but YMMV based on network quality, size of job args, etc.
101
102
  # A large number of jobs can cause a bit of Redis command processing latency.
102
103
  #
103
104
  # Takes the same arguments as #push except that args is expected to be
@@ -105,13 +106,15 @@ module Sidekiq
105
106
  # is run through the client middleware pipeline and each job gets its own Job ID
106
107
  # as normal.
107
108
  #
108
- # Returns an array of the of pushed jobs' jids. The number of jobs pushed can be less
109
- # than the number given if the middleware stopped processing for one or more jobs.
109
+ # Returns an array of the of pushed jobs' jids, may contain nils if any client middleware
110
+ # prevented a job push.
111
+ #
112
+ # Example (pushing jobs in batches):
113
+ # push_bulk('class' => 'MyJob', 'args' => (1..100_000).to_a, batch_size: 1_000)
114
+ #
110
115
  def push_bulk(items)
116
+ batch_size = items.delete(:batch_size) || items.delete("batch_size") || 1_000
111
117
  args = items["args"]
112
- raise ArgumentError, "Bulk arguments must be an Array of Arrays: [[1], [2]]" unless args.is_a?(Array) && args.all?(Array)
113
- return [] if args.empty? # no jobs to push
114
-
115
118
  at = items.delete("at")
116
119
  raise ArgumentError, "Job 'at' must be a Numeric or an Array of Numeric timestamps" if at && (Array(at).empty? || !Array(at).all? { |entry| entry.is_a?(Numeric) })
117
120
  raise ArgumentError, "Job 'at' Array must have same size as 'args' Array" if at.is_a?(Array) && at.size != args.size
@@ -120,18 +123,26 @@ module Sidekiq
120
123
  raise ArgumentError, "Explicitly passing 'jid' when pushing more than one job is not supported" if jid && args.size > 1
121
124
 
122
125
  normed = normalize_item(items)
123
- payloads = args.map.with_index { |job_args, index|
124
- copy = normed.merge("args" => job_args, "jid" => SecureRandom.hex(12))
125
- copy["at"] = (at.is_a?(Array) ? at[index] : at) if at
126
- result = middleware.invoke(items["class"], copy, copy["queue"], @redis_pool) do
127
- verify_json(copy)
128
- copy
129
- end
130
- result || nil
131
- }.compact
126
+ result = args.each_slice(batch_size).flat_map do |slice|
127
+ raise ArgumentError, "Bulk arguments must be an Array of Arrays: [[1], [2]]" unless slice.is_a?(Array) && slice.all?(Array)
128
+ break [] if slice.empty? # no jobs to push
129
+
130
+ payloads = slice.map.with_index { |job_args, index|
131
+ copy = normed.merge("args" => job_args, "jid" => SecureRandom.hex(12))
132
+ copy["at"] = (at.is_a?(Array) ? at[index] : at) if at
133
+ result = middleware.invoke(items["class"], copy, copy["queue"], @redis_pool) do
134
+ verify_json(copy)
135
+ copy
136
+ end
137
+ result || nil
138
+ }
139
+
140
+ to_push = payloads.compact
141
+ raw_push(to_push) unless to_push.empty?
142
+ payloads.map { |payload| payload&.[]("jid") }
143
+ end
132
144
 
133
- raw_push(payloads) unless payloads.empty?
134
- payloads.collect { |payload| payload["jid"] }
145
+ result.is_a?(Enumerator::Lazy) ? result.force : result
135
146
  end
136
147
 
137
148
  # Allows sharding of jobs across any number of Redis instances. All jobs
@@ -160,8 +171,8 @@ module Sidekiq
160
171
  new.push(item)
161
172
  end
162
173
 
163
- def push_bulk(items)
164
- new.push_bulk(items)
174
+ def push_bulk(...)
175
+ new.push_bulk(...)
165
176
  end
166
177
 
167
178
  # Resque compatibility helpers. Note all helpers
@@ -15,7 +15,7 @@ module Sidekiq
15
15
 
16
16
  def safe_thread(name, &block)
17
17
  Thread.new do
18
- Thread.current.name = name
18
+ Thread.current.name = "sidekiq.#{name}"
19
19
  watchdog(name, &block)
20
20
  end
21
21
  end
@@ -30,7 +30,8 @@ module Sidekiq
30
30
  },
31
31
  dead_max_jobs: 10_000,
32
32
  dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
33
- reloader: proc { |&block| block.call }
33
+ reloader: proc { |&block| block.call },
34
+ backtrace_cleaner: ->(backtrace) { backtrace }
34
35
  }
35
36
 
36
37
  ERROR_HANDLER = ->(ex, ctx) {
@@ -38,7 +39,10 @@ module Sidekiq
38
39
  l = cfg.logger
39
40
  l.warn(Sidekiq.dump_json(ctx)) unless ctx.empty?
40
41
  l.warn("#{ex.class.name}: #{ex.message}")
41
- l.warn(ex.backtrace.join("\n")) unless ex.backtrace.nil?
42
+ unless ex.backtrace.nil?
43
+ backtrace = cfg[:backtrace_cleaner].call(ex.backtrace)
44
+ l.warn(backtrace.join("\n"))
45
+ end
42
46
  }
43
47
 
44
48
  def initialize(options = {})
data/lib/sidekiq/fetch.rb CHANGED
@@ -44,7 +44,7 @@ module Sidekiq # :nodoc:
44
44
  return nil
45
45
  end
46
46
 
47
- queue, job = redis { |conn| conn.blocking_call(TIMEOUT + 1, "brpop", *qs, TIMEOUT) }
47
+ queue, job = redis { |conn| conn.blocking_call(conn.read_timeout + TIMEOUT, "brpop", *qs, TIMEOUT) }
48
48
  UnitOfWork.new(queue, job, config) if queue
49
49
  end
50
50
 
data/lib/sidekiq/job.rb CHANGED
@@ -239,11 +239,7 @@ module Sidekiq
239
239
 
240
240
  def perform_bulk(args, batch_size: 1_000)
241
241
  client = @klass.build_client
242
- result = args.each_slice(batch_size).flat_map do |slice|
243
- client.push_bulk(@opts.merge("class" => @klass, "args" => slice))
244
- end
245
-
246
- result.is_a?(Enumerator::Lazy) ? result.force : result
242
+ client.push_bulk(@opts.merge("class" => @klass, "args" => args, :batch_size => batch_size))
247
243
  end
248
244
 
249
245
  # +interval+ must be a timestamp, numeric or something that acts
@@ -71,6 +71,7 @@ module Sidekiq
71
71
  def initialize(capsule)
72
72
  @config = @capsule = capsule
73
73
  @max_retries = Sidekiq.default_configuration[:max_retries] || DEFAULT_MAX_RETRY_ATTEMPTS
74
+ @backtrace_cleaner = Sidekiq.default_configuration[:backtrace_cleaner]
74
75
  end
75
76
 
76
77
  # The global retry handler requires only the barest of data.
@@ -159,10 +160,11 @@ module Sidekiq
159
160
  end
160
161
 
161
162
  if msg["backtrace"]
163
+ backtrace = @backtrace_cleaner.call(exception.backtrace)
162
164
  lines = if msg["backtrace"] == true
163
- exception.backtrace
165
+ backtrace
164
166
  else
165
- exception.backtrace[0...msg["backtrace"].to_i]
167
+ backtrace[0...msg["backtrace"].to_i]
166
168
  end
167
169
 
168
170
  msg["error_backtrace"] = compress_backtrace(lines)
@@ -9,7 +9,7 @@ module Sidekiq
9
9
 
10
10
  def validate(item)
11
11
  raise(ArgumentError, "Job must be a Hash with 'class' and 'args' keys: `#{item}`") unless item.is_a?(Hash) && item.key?("class") && item.key?("args")
12
- raise(ArgumentError, "Job args must be an Array: `#{item}`") unless item["args"].is_a?(Array)
12
+ raise(ArgumentError, "Job args must be an Array: `#{item}`") unless item["args"].is_a?(Array) || item["args"].is_a?(Enumerator::Lazy)
13
13
  raise(ArgumentError, "Job class must be either a Class or String representation of the class name: `#{item}`") unless item["class"].is_a?(Class) || item["class"].is_a?(String)
14
14
  raise(ArgumentError, "Job 'at' must be a Numeric timestamp: `#{item}`") if item.key?("at") && !item["at"].is_a?(Numeric)
15
15
  raise(ArgumentError, "Job tags must be an Array: `#{item}`") if item["tags"] && !item["tags"].is_a?(Array)
@@ -24,7 +24,7 @@ module Sidekiq
24
24
  if (unsafe_item = json_unsafe?(args))
25
25
  msg = <<~EOM
26
26
  Job arguments to #{job_class} must be native JSON types, but #{unsafe_item.inspect} is a #{unsafe_item.class}.
27
- See https://github.com/sidekiq/sidekiq/wiki/Best-Practices.
27
+ See https://github.com/sidekiq/sidekiq/wiki/Best-Practices
28
28
  To disable this error, add `Sidekiq.strict_args!(false)` to your initializer.
29
29
  EOM
30
30
 
@@ -166,7 +166,7 @@ module Sidekiq
166
166
  conn.multi { |transaction|
167
167
  transaction.sadd("processes", [key])
168
168
  transaction.exists(key)
169
- transaction.hmset(key, "info", to_json,
169
+ transaction.hset(key, "info", to_json,
170
170
  "busy", curstate.size,
171
171
  "beat", Time.now.to_f,
172
172
  "rtt_us", rtt,
@@ -70,7 +70,7 @@ module Sidekiq
70
70
  result.job_results[klass].add_metric "ms", time, ms.to_i if ms
71
71
  result.job_results[klass].add_metric "p", time, p.to_i if p
72
72
  result.job_results[klass].add_metric "f", time, f.to_i if f
73
- result.job_results[klass].add_hist time, Histogram.new(klass).fetch(conn, time)
73
+ result.job_results[klass].add_hist time, Histogram.new(klass).fetch(conn, time).reverse
74
74
  time -= 60
75
75
  end
76
76
  end
@@ -29,8 +29,8 @@ module Sidekiq
29
29
  1100, 1700, 2500, 3800, 5750,
30
30
  8500, 13000, 20000, 30000, 45000,
31
31
  65000, 100000, 150000, 225000, 335000,
32
- Float::INFINITY # the "maybe your job is too long" bucket
33
- ]
32
+ 1e20 # the "maybe your job is too long" bucket
33
+ ].freeze
34
34
  LABELS = [
35
35
  "20ms", "30ms", "45ms", "65ms", "100ms",
36
36
  "150ms", "225ms", "335ms", "500ms", "750ms",
@@ -38,7 +38,7 @@ module Sidekiq
38
38
  "8.5s", "13s", "20s", "30s", "45s",
39
39
  "65s", "100s", "150s", "225s", "335s",
40
40
  "Slow"
41
- ]
41
+ ].freeze
42
42
  FETCH = "GET u16 #0 GET u16 #1 GET u16 #2 GET u16 #3 \
43
43
  GET u16 #4 GET u16 #5 GET u16 #6 GET u16 #7 \
44
44
  GET u16 #8 GET u16 #9 GET u16 #10 GET u16 #11 \
@@ -19,7 +19,7 @@ module Sidekiq
19
19
  total_size, items = conn.multi { |transaction|
20
20
  transaction.zcard(key)
21
21
  if rev
22
- transaction.zrevrange(key, starting, ending, withscores: true)
22
+ transaction.zrange(key, starting, ending, "REV", withscores: true)
23
23
  else
24
24
  transaction.zrange(key, starting, ending, withscores: true)
25
25
  end
data/lib/sidekiq/rails.rb CHANGED
@@ -50,6 +50,12 @@ module Sidekiq
50
50
  end
51
51
  end
52
52
 
53
+ initializer "sidekiq.backtrace_cleaner" do
54
+ Sidekiq.configure_server do |config|
55
+ config[:backtrace_cleaner] = ->(backtrace) { ::Rails.backtrace_cleaner.clean(backtrace) }
56
+ end
57
+ end
58
+
53
59
  # This hook happens after all initializers are run, just before returning
54
60
  # from config/environment.rb back to sidekiq/cli.rb.
55
61
  #
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
3
4
  require "redis_client"
4
5
  require "redis_client/decorator"
5
6
 
@@ -8,13 +9,14 @@ module Sidekiq
8
9
  BaseError = RedisClient::Error
9
10
  CommandError = RedisClient::CommandError
10
11
 
12
+ # You can add/remove items or clear the whole thing if you don't want deprecation warnings.
13
+ DEPRECATED_COMMANDS = %i[rpoplpush zrangebyscore zrevrange zrevrangebyscore getset hmset setex setnx].to_set
14
+
11
15
  module CompatMethods
12
- # TODO Deprecate and remove this
13
16
  def info
14
17
  @client.call("INFO") { |i| i.lines(chomp: true).map { |l| l.split(":", 2) }.select { |l| l.size == 2 }.to_h }
15
18
  end
16
19
 
17
- # TODO Deprecate and remove this
18
20
  def evalsha(sha, keys, argv)
19
21
  @client.call("EVALSHA", sha, keys.size, *keys, *argv)
20
22
  end
@@ -24,6 +26,7 @@ module Sidekiq
24
26
  # this allows us to use methods like `conn.hmset(...)` instead of having to use
25
27
  # redis-client's native `conn.call("hmset", ...)`
26
28
  def method_missing(*args, &block)
29
+ warn("[sidekiq#5788] Redis has deprecated the `#{args.first}`command, called at #{caller(1..1)}") if DEPRECATED_COMMANDS.include?(args.first)
27
30
  @client.call(*args, *block)
28
31
  end
29
32
  ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
@@ -39,28 +42,6 @@ module Sidekiq
39
42
  def config
40
43
  @client.config
41
44
  end
42
-
43
- def message
44
- yield nil, @queue.pop
45
- end
46
-
47
- # NB: this method does not return
48
- def subscribe(chan)
49
- @queue = ::Queue.new
50
-
51
- pubsub = @client.pubsub
52
- pubsub.call("subscribe", chan)
53
-
54
- loop do
55
- evt = pubsub.next_event
56
- next if evt.nil?
57
- next unless evt[0] == "message" && evt[1] == chan
58
-
59
- (_, _, msg) = evt
60
- @queue << msg
61
- yield self
62
- end
63
- end
64
45
  end
65
46
 
66
47
  def initialize(options)
@@ -12,7 +12,7 @@ module Sidekiq
12
12
 
13
13
  LUA_ZPOPBYSCORE = <<~LUA
14
14
  local key, now = KEYS[1], ARGV[1]
15
- local jobs = redis.call("zrangebyscore", key, "-inf", now, "limit", 0, 1)
15
+ local jobs = redis.call("zrange", key, "-inf", now, "byscore", "limit", 0, 1)
16
16
  if jobs[1] then
17
17
  redis.call("zrem", key, jobs[1])
18
18
  return jobs[1]
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "7.0.8"
4
+ VERSION = "7.1.0"
5
5
  MAJOR = 7
6
6
  end
data/sidekiq.gemspec CHANGED
@@ -23,17 +23,8 @@ Gem::Specification.new do |gem|
23
23
  "rubygems_mfa_required" => "true"
24
24
  }
25
25
 
26
- gem.add_dependency "redis-client", ">= 0.11.0"
26
+ gem.add_dependency "redis-client", ">= 0.14.0"
27
27
  gem.add_dependency "connection_pool", ">= 2.3.0"
28
28
  gem.add_dependency "rack", ">= 2.2.4"
29
29
  gem.add_dependency "concurrent-ruby", "< 2"
30
- gem.post_install_message = <<~EOM
31
-
32
- Welcome to Sidekiq 7.0!
33
-
34
- 1. Use `gem 'sidekiq', '<7'` in your Gemfile if you don't want this new version.
35
- 2. Read the release notes at https://github.com/sidekiq/sidekiq/blob/main/docs/7.0-Upgrade.md
36
- 3. If you have problems, search for open/closed issues at https://github.com/sidekiq/sidekiq/issues/
37
-
38
- EOM
39
30
  end
data/web/locales/fr.yml CHANGED
@@ -17,14 +17,17 @@ fr:
17
17
  DeadJobs: Tâches mortes
18
18
  Delete: Supprimer
19
19
  DeleteAll: Tout supprimer
20
+ Deploy: Déploiement
20
21
  Enqueued: En attente
21
22
  Error: Erreur
22
23
  ErrorBacktrace: Backtrace d’erreur
23
24
  ErrorClass: Classe d’erreur
24
25
  ErrorMessage: Message d’erreur
26
+ ExecutionTime: Temps d'exécution
25
27
  Extras: Extras
26
28
  Failed: Échouées
27
29
  Failures: Echecs
30
+ Failure: Echec
28
31
  GoBack: ← Retour
29
32
  History: Historique
30
33
  Job: Tâche
@@ -35,6 +38,7 @@ fr:
35
38
  Latency: Latence
36
39
  LivePoll: Temps réel
37
40
  MemoryUsage: Mémoire utilisée
41
+ Name: Nom
38
42
  Namespace: Namespace
39
43
  NextRetry: Prochain essai
40
44
  NoDeadJobsFound: Aucune tâche morte n'a été trouvée
@@ -63,6 +67,7 @@ fr:
63
67
  RetryNow: Réessayer maintenant
64
68
  Scheduled: Planifiées
65
69
  ScheduledJobs: Tâches planifiées
70
+ Seconds: Secondes
66
71
  ShowAll: Tout montrer
67
72
  SixMonths: 6 mois
68
73
  Size: Taille
@@ -71,6 +76,8 @@ fr:
71
76
  Stop: Arrêter
72
77
  StopAll: Tout arrêter
73
78
  StopPolling: Arrêt du temps réel
79
+ Success: Succès
80
+ Summary: Résumé
74
81
  Thread: Thread
75
82
  Threads: Threads
76
83
  ThreeMonths: 3 mois
@@ -83,3 +90,10 @@ fr:
83
90
  Worker: Travailleur
84
91
  active: actif
85
92
  idle: inactif
93
+ Metrics: Métriques
94
+ NoDataFound: Aucune donnée disponible
95
+ TotalExecutionTime: Temps d'exécution total
96
+ AvgExecutionTime: Temps d'exécution moyen
97
+ Context: Contexte
98
+ Bucket: Bucket
99
+ NoJobMetricsFound: Aucune statistique de tâche récente n'a été trouvée
@@ -0,0 +1,99 @@
1
+ # elements like %{queue} are variables and should not be translated
2
+ gd:
3
+ Actions: Gnìomhan
4
+ AddToQueue: Cuir ris a’ chiutha
5
+ AreYouSure: A bheil thu cinnteach?
6
+ AreYouSureDeleteJob: A bheil thu cinnteach gu bheil thu airson an obair seo a sguabadh às?
7
+ AreYouSureDeleteQueue: A bheil thu cinnteach gu bheil thu airson ciutha %{queue} a sguabadh às? Sguabaidh seo às gach obair sa chiutha seo, nochdaidh e a-rithist nuair a phutas tu barrachd obraichean dha an uairsin.
8
+ Arguments: Argamaidean
9
+ BackToApp: Till dhan aplacaid
10
+ Busy: Trang
11
+ Class: Clas
12
+ Connections: Ceanglaichean
13
+ CreatedAt: Air a chruthachadh
14
+ CurrentMessagesInQueue: Obraichean làithreach am broinn <span class='title'>%{queue}</span>
15
+ Dashboard: Deas-bhòrd
16
+ Dead: Marbh
17
+ DeadJobs: Obraichean marbh
18
+ Delete: Sguab às
19
+ DeleteAll: Sguab às na h-uile
20
+ Deploy: Cuir an gnìomh
21
+ Enqueued: Sa chiutha
22
+ Error: Mearachd
23
+ ErrorBacktrace: Backtrace na mearachd
24
+ ErrorClass: Clas na mearachd
25
+ ErrorMessage: Teachdaireachd na mearachd
26
+ ExecutionTime: Àm a’ ghnìomha
27
+ Extras: Nithean a bharrachd
28
+ Failed: Air fàilligeadh
29
+ Failures: Fàilligidhean
30
+ Failure: Fàilligeadh
31
+ GoBack: ← Air ais
32
+ History: Eachdraidh
33
+ Job: Obair
34
+ Jobs: Obraichean
35
+ Kill: Marbh
36
+ KillAll: Marbh na h-uile
37
+ LastRetry: An oidhirp mu dheireadh
38
+ Latency: Foillidheachd
39
+ LivePoll: Ath-nuadhachadh beò
40
+ MemoryUsage: Cleachdadh a’ chuimhne
41
+ Name: Ainm
42
+ Namespace: Ainm-spàs
43
+ NextRetry: An ath-oidhirp
44
+ NoDeadJobsFound: Cha deach obair mharbh a lorg
45
+ NoRetriesFound: Cha deach ath-oidhirp a lorg
46
+ NoScheduledFound: Cha deach obair air an sgeideal a lorg
47
+ NotYetEnqueued: Chan eil seo sa chiutha fhathast
48
+ OneMonth: Mìos
49
+ OneWeek: Seachdain
50
+ OriginallyFailed: Dh’fhàillig e o thùs
51
+ Pause: Cuir ’na stad
52
+ Paused: ’Na stad
53
+ PeakMemoryUsage: Bàrr cleachdadh a’ chuimhne
54
+ Plugins: Plugain
55
+ PollingInterval: Eadaramh an ath-nuadhachaidh
56
+ Process: Pròiseas
57
+ Processed: Air pròiseasadh
58
+ Processes: Pròiseasan
59
+ Queue: Ciutha
60
+ Queues: Ciuthan
61
+ Quiet: Mùch
62
+ QuietAll: Mùch na h-uile
63
+ Realtime: Fìor-àm
64
+ Retries: Oidhirpean
65
+ RetryAll: Feuch ris na h-uile a-rithist
66
+ RetryCount: Cunntas nan oidhirpean
67
+ RetryNow: Feuch ris a-rithist an-dràsta
68
+ Scheduled: Air an sgeideal
69
+ ScheduledJobs: Obraichean air an sgeideal
70
+ Seconds: Diogan
71
+ ShowAll: Seall na h-uile
72
+ SixMonths: Leth-bhliadhna
73
+ Size: Meud
74
+ Started: Air a thòiseachadh
75
+ Status: Staid
76
+ Stop: Cuir stad air
77
+ StopAll: Cuir stad air na h-uile
78
+ StopPolling: Sguir dhen ath-nuadhachadh
79
+ Success: Chaidh leis
80
+ Summary: Geàrr-chunntas
81
+ Thread: Snàithlean
82
+ Threads: Snàithleanan
83
+ ThreeMonths: 3 mìosan
84
+ Time: Àm
85
+ Unpause: Lean air
86
+ Uptime: Beò fad (làithean)
87
+ Utilization: Cleachdadh
88
+ Version: Tionndadh
89
+ When: Cuin
90
+ Worker: Obraiche
91
+ active: gnìomhach
92
+ idle: ’na thàmh
93
+ Metrics: Meatraigeachd
94
+ NoDataFound: Cha deach dàta a lorg
95
+ TotalExecutionTime: Ùine iomlan nan gnìomhan
96
+ AvgExecutionTime: Ùine cuibheasach nan gnìomhan
97
+ Context: Co-theacsa
98
+ Bucket: Bucaid
99
+ NoJobMetricsFound: Cha deach meatraigeachd o chionn goirid air obair a lorg
data/web/views/busy.erb CHANGED
@@ -33,8 +33,8 @@
33
33
  <form method="POST" class="warning-messages">
34
34
  <%= csrf_tag %>
35
35
  <div class="btn-group pull-right flip">
36
- <button class="btn btn-warn" type="submit" name="quiet" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('QuietAll') %></button>
37
- <button class="btn btn-danger" type="submit" name="stop" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('StopAll') %></button>
36
+ <input class="btn btn-warn" type="submit" name="quiet" value="<%= t('QuietAll') %>" data-confirm="<%= t('AreYouSure') %>"/>
37
+ <input class="btn btn-danger" type="submit" name="stop" value="<%= t('StopAll') %>" data-confirm="<%= t('AreYouSure') %>"/>
38
38
  </div>
39
39
  </form>
40
40
  </div>
@@ -5,12 +5,9 @@
5
5
 
6
6
  <%
7
7
  job_result = @query_result.job_results[@name]
8
- hist_totals = job_result.hist.values.first.zip(*job_result.hist.values[1..-1]).map(&:sum)
9
- bucket_labels =Sidekiq::Metrics::Histogram::LABELS
10
- bucket_intervals =Sidekiq::Metrics::Histogram::BUCKET_INTERVALS.reverse
11
-
12
- # Replace INFINITY since it can't be represented as JSON
13
- bucket_intervals[0] = bucket_intervals[1] * 2
8
+ hist_totals = job_result.hist.values.first.zip(*job_result.hist.values[1..-1]).map(&:sum).reverse
9
+ bucket_labels = Sidekiq::Metrics::Histogram::LABELS
10
+ bucket_intervals = Sidekiq::Metrics::Histogram::BUCKET_INTERVALS
14
11
  %>
15
12
 
16
13
  <% if job_result.totals["s"] > 0 %>
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: 7.0.8
4
+ version: 7.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-05 00:00:00.000000000 Z
11
+ date: 2023-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.11.0
19
+ version: 0.14.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.11.0
26
+ version: 0.14.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: connection_pool
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +156,7 @@ files:
156
156
  - web/locales/es.yml
157
157
  - web/locales/fa.yml
158
158
  - web/locales/fr.yml
159
+ - web/locales/gd.yml
159
160
  - web/locales/he.yml
160
161
  - web/locales/hi.yml
161
162
  - web/locales/it.yml
@@ -206,14 +207,7 @@ metadata:
206
207
  changelog_uri: https://github.com/sidekiq/sidekiq/blob/main/Changes.md
207
208
  source_code_uri: https://github.com/sidekiq/sidekiq
208
209
  rubygems_mfa_required: 'true'
209
- post_install_message: |2+
210
-
211
- Welcome to Sidekiq 7.0!
212
-
213
- 1. Use `gem 'sidekiq', '<7'` in your Gemfile if you don't want this new version.
214
- 2. Read the release notes at https://github.com/sidekiq/sidekiq/blob/main/docs/7.0-Upgrade.md
215
- 3. If you have problems, search for open/closed issues at https://github.com/sidekiq/sidekiq/issues/
216
-
210
+ post_install_message:
217
211
  rdoc_options: []
218
212
  require_paths:
219
213
  - lib
@@ -233,4 +227,3 @@ signing_key:
233
227
  specification_version: 4
234
228
  summary: Simple, efficient background processing for Ruby
235
229
  test_files: []
236
- ...