resque-scheduler 4.11.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4ecd4f957b7c3df8c89bc85ffb8951b5df6cc18b004379b29ebcfc3be982621
4
- data.tar.gz: 7aacc351234c1f367d8b73cda10d43b97ff26e89a3319e0afa76b51abea70430
3
+ metadata.gz: 046040c8fa18b0cb7aabc7fdc46ff008f7b0c30f9aa0500137f5c6c987bdbabc
4
+ data.tar.gz: b3e243c3c9ccefa0c1282b492b70a9b26677fa2b4be6ead096e339c721d9f86a
5
5
  SHA512:
6
- metadata.gz: e668259967505827e06a40a83cb2e3b7c7c165df440c914c8e688c4d871594c46ac512ebb8a99856f4e3cf37f45625f5144bc6beeda1157c7b2d146eec9055cc
7
- data.tar.gz: 32e7b921643fb62600d133db156c5f4c28d863a893a92d18ba1b1f7317b0371dd38cd11b0a1e2adcccfa211265f9d285b452d2e524d3637487e7c982c8563032
6
+ metadata.gz: 8b6c3caa8b47c24aee900d2c348cabb20d1a32a5fce88e02a974649ca6c711b1703562393902c7638e14c1a11180b1901b126480e905c7cca8b2dbd47d27daa3
7
+ data.tar.gz: 7b2665804103943b3bf9a98b84134ba71a0ac00ace8e0c2ed7c765873445c801bea14c8ae9082fec4133e6f3be0314bdf1485ecd47c7bab8aba6d8d85ef36ec8
@@ -0,0 +1,42 @@
1
+ # Use Ruby 3.3 as specified in the test matrix
2
+ FROM ruby:3.3
3
+
4
+ # Install dependencies
5
+ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
6
+ && apt-get -y install --no-install-recommends \
7
+ git \
8
+ build-essential \
9
+ libssl-dev \
10
+ libreadline-dev \
11
+ zlib1g-dev \
12
+ redis-tools \
13
+ && apt-get clean \
14
+ && rm -rf /var/lib/apt/lists/*
15
+
16
+ # Create a non-root user
17
+ ARG USERNAME=vscode
18
+ ARG USER_UID=1000
19
+ ARG USER_GID=$USER_UID
20
+
21
+ RUN groupadd --gid $USER_GID $USERNAME \
22
+ && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
23
+ && apt-get update \
24
+ && apt-get install -y sudo \
25
+ && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
26
+ && chmod 0440 /etc/sudoers.d/$USERNAME
27
+
28
+ # Set the default user
29
+ USER $USERNAME
30
+
31
+ # Set working directory
32
+ WORKDIR /workspaces/resque-scheduler
33
+
34
+ # Install bundler
35
+ RUN gem install bundler
36
+
37
+ # Set environment variables for the test matrix configuration
38
+ ENV REDIS_VERSION=latest
39
+ ENV RESQUE=master
40
+ ENV RUFUS_SCHEDULER=3.6
41
+ ENV RACK_VERSION=3
42
+ ENV COVERAGE=1
@@ -0,0 +1,111 @@
1
+ # Dev Container for Resque Scheduler
2
+
3
+ This dev container is configured to match the GitHub Actions test matrix with the following configuration:
4
+
5
+ - **Ruby version**: 3.3
6
+ - **Resque version**: master (from git)
7
+ - **Rufus-scheduler**: 3.6
8
+ - **Redis version**: latest
9
+ - **Rack version**: 3
10
+
11
+ ## Getting Started
12
+
13
+ 1. Open this repository in VS Code
14
+ 2. When prompted, click "Reopen in Container" (or run the command "Dev Containers: Reopen in Container")
15
+ 3. Wait for the container to build and start
16
+ 4. Once inside the container, dependencies will be automatically installed via `bundle install`
17
+
18
+ ## Running Tests
19
+
20
+ To run the full test suite:
21
+
22
+ ```bash
23
+ bundle exec rake
24
+ ```
25
+
26
+ To run a specific test file:
27
+
28
+ ```bash
29
+ bundle exec ruby test/scheduler_test.rb
30
+ ```
31
+
32
+ To run tests with verbose output:
33
+
34
+ ```bash
35
+ VERBOSE=1 bundle exec rake
36
+ ```
37
+
38
+ To run tests matching a specific pattern:
39
+
40
+ ```bash
41
+ PATTERN='test/scheduler_*_test.rb' bundle exec rake
42
+ ```
43
+
44
+ ## Testing with Different Configurations
45
+
46
+ If you want to test with different versions, you can modify the environment variables and reinstall dependencies:
47
+
48
+ ```bash
49
+ # Example: Test with rufus-scheduler 3.4
50
+ export RUFUS_SCHEDULER=3.4
51
+ bundle install
52
+
53
+ # Run tests
54
+ bundle exec rake
55
+
56
+ # Reset to original configuration
57
+ export RUFUS_SCHEDULER=3.6
58
+ bundle install
59
+ ```
60
+
61
+ ## Available Environment Variables
62
+
63
+ The following environment variables are set to match the test matrix:
64
+
65
+ - `REDIS_VERSION`: latest
66
+ - `RESQUE`: master
67
+ - `RUFUS_SCHEDULER`: 3.6
68
+ - `RACK_VERSION`: 3
69
+ - `COVERAGE`: 1
70
+
71
+ ## Services
72
+
73
+ ### Redis
74
+ Redis is available at `redis://redis:6379` or via `localhost:6379` from within the container.
75
+
76
+ To connect to Redis CLI:
77
+
78
+ ```bash
79
+ redis-cli -h redis
80
+ ```
81
+
82
+ ## Troubleshooting
83
+
84
+ ### Bundle Install Issues
85
+
86
+ If you encounter issues with bundle install, try:
87
+
88
+ ```bash
89
+ bundle config set --local build.redis --with-cflags="-Wno-error=implicit-function-declaration"
90
+ bundle install
91
+ ```
92
+
93
+ ### Redis Connection Issues
94
+
95
+ Make sure Redis is running:
96
+
97
+ ```bash
98
+ redis-cli -h redis ping
99
+ ```
100
+
101
+ Should return `PONG`.
102
+
103
+ ### Rebuilding the Container
104
+
105
+ If you need to rebuild the container from scratch:
106
+
107
+ 1. Run "Dev Containers: Rebuild Container" from the command palette
108
+ 2. Or delete the container and volume manually:
109
+ ```bash
110
+ docker-compose -f .devcontainer/docker-compose.yml down -v
111
+ ```
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "Resque Scheduler Dev Container",
3
+ "dockerComposeFile": "docker-compose.yml",
4
+ "service": "app",
5
+ "workspaceFolder": "/workspaces/resque-scheduler",
6
+
7
+ // Features to add to the dev container
8
+ "features": {
9
+ "ghcr.io/devcontainers/features/git:1": {}
10
+ },
11
+
12
+ // Configure tool-specific properties
13
+ "customizations": {
14
+ "vscode": {
15
+ "extensions": [
16
+ "rebornix.ruby"
17
+ ],
18
+ "settings": {
19
+ "terminal.integrated.defaultProfile.linux": "bash"
20
+ }
21
+ }
22
+ },
23
+
24
+ // Use 'forwardPorts' to make a list of ports inside the container available locally
25
+ "forwardPorts": [6379],
26
+
27
+ // Use 'postCreateCommand' to run commands after the container is created
28
+ "postCreateCommand": "bundle install",
29
+
30
+ // Set environment variables for the test matrix
31
+ "containerEnv": {
32
+ "REDIS_VERSION": "latest",
33
+ "RESQUE": "master",
34
+ "RUFUS_SCHEDULER": "3.6",
35
+ "RACK_VERSION": "3",
36
+ "COVERAGE": "1"
37
+ },
38
+
39
+ // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root
40
+ "remoteUser": "vscode"
41
+ }
@@ -0,0 +1,31 @@
1
+ services:
2
+ app:
3
+ build:
4
+ context: .
5
+ dockerfile: Dockerfile
6
+ volumes:
7
+ - ../..:/workspaces:cached
8
+ working_dir: /workspaces/resque-scheduler
9
+ command: sleep infinity
10
+ environment:
11
+ REDIS_VERSION: "latest"
12
+ RESQUE: "master"
13
+ RUFUS_SCHEDULER: "3.6"
14
+ RACK_VERSION: "3"
15
+ COVERAGE: "1"
16
+ REDIS_URL: "redis://redis:6379"
17
+ depends_on:
18
+ - redis
19
+ # Runs app on the same network as the redis container, allows "forwardPorts" in devcontainer.json function
20
+ network_mode: service:redis
21
+
22
+ redis:
23
+ image: redis:latest
24
+ restart: unless-stopped
25
+ ports:
26
+ - "6379:6379"
27
+ volumes:
28
+ - redis-data:/data
29
+
30
+ volumes:
31
+ redis-data:
@@ -14,7 +14,7 @@ jobs:
14
14
  matrix:
15
15
  os: [ubuntu-latest]
16
16
  ruby: [
17
- 2.7
17
+ 3.4
18
18
  ]
19
19
 
20
20
  steps:
@@ -19,57 +19,29 @@ jobs:
19
19
  fail-fast: false
20
20
  matrix:
21
21
  ruby-version:
22
- - 2.3
23
- - 2.4
24
- - 2.5
25
- - 2.6
26
- - 2.7
27
22
  - "3.0"
28
23
  - 3.1
29
24
  - 3.2
30
25
  - 3.3
26
+ - 3.4
27
+ - head
31
28
  resque-version:
32
29
  - "master"
33
- - "~> 2.4.0"
34
- - "~> 1.27"
35
30
  rufus-scheduler:
36
- - "3.2"
37
31
  - "3.4"
38
32
  - "3.5"
39
33
  - "3.6"
40
34
  redis-version:
41
- - "~> 4.x"
42
- - "~> 5.x"
43
- exclude:
44
- - ruby-version: head
45
- rufus-scheduler: 3.2
46
- - ruby-version: 3.2
47
- rufus-scheduler: 3.2
48
-
49
- - ruby-version: 2.3
50
- resque-version: "~> 1.27"
51
- rufus-scheduler: 3.4
52
- - ruby-version: 2.3
53
- resque-version: "~> 1.27"
54
- rufus-scheduler: 3.5
55
- - ruby-version: 2.5
56
- resque-version: "~> 2.4.0"
57
- rufus-scheduler: 3.5
58
- - ruby-version: 2.5
59
- resque-version: master
60
- rufus-scheduler: 3.2
61
-
62
- - ruby-version: 2.3
63
- redis-version: "~> 5.x"
64
- - ruby-version: 2.4
65
- redis-version: "~> 5.x"
66
-
67
- - resque-version: "~> 1.27"
68
- redis-version: "~> 5.x"
35
+ - "4.8"
36
+ - "latest"
37
+ rack-version:
38
+ - 2
39
+ - 3
69
40
  env:
70
41
  REDIS_VERSION: "${{ matrix.redis-version }}"
71
42
  RESQUE: "${{ matrix.resque-version }}"
72
43
  RUFUS_SCHEDULER: "${{ matrix.rufus-scheduler }}"
44
+ RACK_VERSION: "${{ matrix.rack-version }}"
73
45
  COVERAGE: 1
74
46
 
75
47
  steps:
data/CHANGELOG.md CHANGED
@@ -2,7 +2,54 @@
2
2
 
3
3
  **ATTN**: This project uses [semantic versioning](http://semver.org/).
4
4
 
5
- ## [4.10.3] - 2024-12-30
5
+ ## [5.0.1] - 2026-10-11
6
+ ### Changed
7
+ * Pipeline `count_all_scheduled_jobs` for significantly faster execution by @top-sigrid in #822
8
+ * Avoid unnecessary reloads in static mode by @ekmartin in #823
9
+
10
+ ### Fixed
11
+ * Skip invalid schedules without interrupting scheduler loading by @taf2 in #543
12
+ * Encode a delayed job once so its timestamps key can be cleaned up by @kamaljoshi in #827 (originally #599)
13
+ * Log to the logfile when backgrounded by @meatballhat in #828 (originally #568)
14
+ * Require redis before using its error classes by @neuromanskie in #829
15
+ * Fix flaky test by using strings instead of symbols for JSON-serialized args by @top-sigrid in #813
16
+
17
+ ### Security
18
+ * Escape job class and queue names in the scheduler web UI by @PatrickTulskie in #830
19
+ * Escape schedule names and parameters on the requeue params page by @PatrickTulskie in #831
20
+ * Escape the scheduler environment and master lock holder on the schedule page by @PatrickTulskie in #832
21
+
22
+ ## [5.0.0] - 2026-01-15
23
+ ### Breaking Changes
24
+ * Ruby requirement: `>= 2.3.0` → `>= 3.0.0`
25
+ * Resque dependency: `>= 1.27` → `>= 3.0`
26
+ * Redis dependency: `>= 3.3` → `>= 4.0`
27
+ * Removed `rack < 3` constraint
28
+
29
+ ### Added
30
+ * Add Ruby 3.4 to the CI matrix by @and9000 in #804
31
+ * Added `base64 ~> 0.1` runtime dependency (Ruby 3.4+ compatibility) by @PatrickTulskie in #809
32
+ * Added `irb` dev dependency (Ruby 4+ compatibility) by @PatrickTulskie in #809
33
+ * Added Rack 2/3 matrix testing by @PatrickTulskie in #809
34
+
35
+ ### Changed
36
+ * Prepare for resque 3.0 compatibility by @PatrickTulskie in #809
37
+ * CI now tests Ruby 3.0-3.4 + head only (removed Ruby 2.x)
38
+ * Simplified to test against resque master only
39
+ * Modernized `.rubocop.yml` to `DisabledByDefault: true` approach
40
+ * Set `TargetRubyVersion: 3.0`
41
+ * Updated rubocop: `~> 0.40.0` → `~> 0.80`
42
+ * Use `JSON.parse` instead of `JSON.load` (security improvement) by @PatrickTulskie in #809
43
+ * Use `URI.decode_www_form_component` instead of `CGI.unescape` by @PatrickTulskie in #809
44
+ * Consistent time formatting in views by @PatrickTulskie in #809
45
+
46
+ ### Fixed
47
+ * Fix `Resque::Scheduler.print_schedule` by @codealchemy in #794
48
+ * Remove circular require for resque from resque-scheduler by @zzak in #795
49
+ * Fixed test compatibility with Rack 3 by @PatrickTulskie in #809
50
+ * Fixed race condition in scheduler task tests by @PatrickTulskie in #809
51
+
52
+ ## [4.11.0] - 2024-12-30
6
53
  ### Added
7
54
  * Expose timeout for lock via environment variable configuration by @pmm4654 in #786
8
55
  * Add Ruby 3.3 to the CI matrix by @santiagorodriguez96 in #797
data/Gemfile CHANGED
@@ -24,6 +24,13 @@ else
24
24
  gem 'redis', redis_version
25
25
  end
26
26
 
27
+ rack_version = ENV.fetch('RACK_VERSION', '3')
28
+ gem 'rack', "~> #{rack_version}.0"
29
+
30
+ if rack_version.to_i >= 3
31
+ gem 'rackup'
32
+ end
33
+
27
34
  gem 'sinatra', '> 2.0'
28
35
 
29
36
  gemspec
@@ -1,5 +1,4 @@
1
1
  # vim:fileencoding=utf-8
2
- require 'resque'
3
2
  require_relative 'plugin'
4
3
  require_relative '../scheduler'
5
4
 
@@ -84,11 +83,13 @@ module Resque
84
83
  # insertion time complexity is O(log(n)). Returns true if it's
85
84
  # the first job to be scheduled at that time, else false.
86
85
  def delayed_push(timestamp, item)
86
+ encoded_job = encode(item)
87
+
87
88
  # First add this item to the list for this timestamp
88
- redis.rpush("delayed:#{timestamp.to_i}", encode(item))
89
+ redis.rpush("delayed:#{timestamp.to_i}", encoded_job)
89
90
 
90
91
  # Store the timestamps at with this item occurs
91
- redis.sadd("timestamps:#{encode(item)}", ["delayed:#{timestamp.to_i}"])
92
+ redis.sadd("timestamps:#{encoded_job}", ["delayed:#{timestamp.to_i}"])
92
93
 
93
94
  # Now, add this timestamp to the zsets. The score and the value are
94
95
  # the same since we'll be querying by timestamp, and we don't have
@@ -262,12 +263,18 @@ module Resque
262
263
  count
263
264
  end
264
265
 
266
+ # Counts all jobs across all delayed timestamps.
267
+ # Uses pipelined LLEN calls in batches to avoid blocking the Redis thread
268
+ # for too long while being significantly faster than sequential calls.
265
269
  def count_all_scheduled_jobs
266
- total_jobs = 0
267
- Array(redis.zrange(:delayed_queue_schedule, 0, -1)).each do |ts|
268
- total_jobs += redis.llen("delayed:#{ts}").to_i
270
+ timestamps = Array(redis.zrange(:delayed_queue_schedule, 0, -1))
271
+ return 0 if timestamps.empty?
272
+
273
+ timestamps.each_slice(10_000).sum do |batch|
274
+ redis.pipelined do |pipeline|
275
+ batch.each { |ts| pipeline.llen("delayed:#{ts}") }
276
+ end.sum
269
277
  end
270
- total_jobs
271
278
  end
272
279
 
273
280
  # Discover if a job has been delayed.
@@ -30,18 +30,18 @@ module Resque
30
30
  def setup_backgrounding
31
31
  return unless options[:background]
32
32
 
33
- # Need to set this here for conditional Process.daemon redirect of
34
- # stderr/stdout to /dev/null
35
- Resque::Scheduler.quiet = if options.key?(:quiet)
36
- !!options[:quiet]
37
- else
38
- true
39
- end
33
+ Resque::Scheduler.quiet = background_quiet?
40
34
 
41
35
  Process.daemon(true, !Resque::Scheduler.quiet)
42
36
  Resque.redis.reconnect
43
37
  end
44
38
 
39
+ def background_quiet?
40
+ return !!options[:quiet] if options.key?(:quiet)
41
+ return false if options.key?(:logfile)
42
+ !!options[:background]
43
+ end
44
+
45
45
  def setup_pid_file
46
46
  return unless options[:pidfile]
47
47
 
@@ -8,7 +8,7 @@
8
8
  <% @timestamps.each do |t| %>
9
9
  <tr>
10
10
  <td>
11
- <%= Time.at(t) %>
11
+ <%= format_time(Time.at(t)) %>
12
12
  </td>
13
13
  </tr>
14
14
  <% end %>
@@ -12,7 +12,7 @@
12
12
  <% jobs = resque.delayed_timestamp_peek(timestamp, start, 20) %>
13
13
  <% jobs.each do |job| %>
14
14
  <tr>
15
- <td class='class'><%= job['class'] %></td>
15
+ <td class='class'><%= h job['class'] %></td>
16
16
  <td class='args'><%= h show_job_arguments(job['args']) %></td>
17
17
  </tr>
18
18
  <% end %>
@@ -1,4 +1,4 @@
1
- <h1><%= @job_name %></h1>
1
+ <h1><%= h @job_name %></h1>
2
2
 
3
3
  <p class='intro'>
4
4
  This job requires parameters:
@@ -10,14 +10,14 @@
10
10
  <% value ||= {} %>
11
11
  <tr>
12
12
  <td>
13
- <%= key %>
13
+ <%= h key %>
14
14
  <% if value['description'] || value[:description] %>
15
- <span style="border-bottom:1px dotted;" title="<%=value ['description'] || value[:description] %>">(?)</span>
15
+ <span style="border-bottom:1px dotted;" title="<%= h(value['description'] || value[:description]) %>">(?)</span>
16
16
  <% end %>:
17
17
  </td>
18
- <td><input type="text" name="<%= key %>" value="<%= value['default'] || value[:default] %>"></td>
18
+ <td><input type="text" name="<%= h key %>" value="<%= h(value['default'] || value[:default]) %>"></td>
19
19
  <% end %>
20
20
  </table>
21
- <input type="hidden" name="job_name" value="<%= @job_name %>">
21
+ <input type="hidden" name="job_name" value="<%= h @job_name %>">
22
22
  <input type="submit" value="Queue now">
23
23
  </form>
@@ -4,8 +4,8 @@
4
4
  The list below contains all scheduled jobs. Click &quot;Queue now&quot; to queue
5
5
  a job immediately.
6
6
  <br/> Server local time: <%= Time.now %>
7
- <br/> Server Environment: <%= Resque::Scheduler.env %>
8
- <br/> Current master: <%= Resque.redis.get(Resque::Scheduler.master_lock.key) %>
7
+ <br/> Server Environment: <%= h Resque::Scheduler.env %>
8
+ <br/> Current master: <%= h Resque.redis.get(Resque::Scheduler.master_lock.key) %>
9
9
  </p>
10
10
  <p class='intro'>
11
11
  The highlighted jobs are skipped for current environment.
@@ -22,13 +22,13 @@
22
22
  <td style="padding-top: 12px; padding-bottom: 2px; width: 10px">
23
23
  <form action="<%= u "/delayed/cancel_now" %>" method="post">
24
24
  <input type="hidden" name="timestamp" value="<%= job['timestamp'].to_i %>">
25
- <input type="hidden" name="klass" value="<%= job['class'] %>">
25
+ <input type="hidden" name="klass" value="<%= h job['class'] %>">
26
26
  <input type="hidden" name="args" value="<%= h(Resque.encode job['args']) %>">
27
27
  <input type="submit" value="Cancel Job">
28
28
  </form>
29
29
  </td>
30
30
  <td class='args'><%= format_time(Time.at(job['timestamp'])) %></td>
31
- <td class='class'><%= job['class'] %></td>
31
+ <td class='class'><%= h job['class'] %></td>
32
32
  <td class='args'><%= h job['args'].inspect %></td>
33
33
  </tr>
34
34
  <% end %>
@@ -44,8 +44,8 @@
44
44
  </tr>
45
45
  <% queued.each do |job| %>
46
46
  <tr>
47
- <td class='class'><%= job['queue'] %></td>
48
- <td class='class'><%= job['class'] %></td>
47
+ <td class='class'><%= h job['queue'] %></td>
48
+ <td class='class'><%= h job['class'] %></td>
49
49
  <td class='args'><%= h job['args'].inspect %></td>
50
50
  </tr>
51
51
  <% end %>
@@ -61,8 +61,8 @@
61
61
  </tr>
62
62
  <% working.each do |job| %>
63
63
  <tr>
64
- <td class='class'><%= job['queue'] %></td>
65
- <td class='class'><%= job['class'] %></td>
64
+ <td class='class'><%= h job['queue'] %></td>
65
+ <td class='class'><%= h job['class'] %></td>
66
66
  <td class='args'><%= h job['args'].inspect %></td>
67
67
  </tr>
68
68
  <% end %>
@@ -87,9 +87,11 @@ module Resque
87
87
  def delayed_jobs_klass
88
88
  begin
89
89
  klass = Resque::Scheduler::Util.constantize(params[:klass])
90
- @args = JSON.load(CGI.unescape(params[:args]))
90
+ args_param = params[:args] || params['args']
91
+ @args = args_param ? JSON.parse(URI.decode_www_form_component(args_param)) : []
91
92
  @timestamps = Resque.scheduled_at(klass, *@args)
92
93
  rescue
94
+ @args = []
93
95
  @timestamps = []
94
96
  end
95
97
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Resque
4
4
  module Scheduler
5
- VERSION = '4.11.0'.freeze
5
+ VERSION = '5.0.1'.freeze
6
6
  end
7
7
  end
@@ -1,6 +1,6 @@
1
1
  # vim:fileencoding=utf-8
2
2
 
3
- require 'redis/errors'
3
+ require 'redis'
4
4
  require 'rufus/scheduler'
5
5
  require_relative 'scheduler/configuration'
6
6
  require_relative 'scheduler/locking'
@@ -49,6 +49,7 @@ module Resque
49
49
  $stderr.sync = true
50
50
 
51
51
  was_master = nil
52
+ schedule_loaded = false
52
53
 
53
54
  begin
54
55
  @th = Thread.current
@@ -61,8 +62,14 @@ module Resque
61
62
  if am_master != was_master
62
63
  procline am_master ? 'Master scheduler' : 'Child scheduler'
63
64
 
64
- # Load schedule because changed
65
- reload_schedule!
65
+ # The first pass always loads the schedule - load_schedule!
66
+ # reads am_master, so it cannot run before the check above.
67
+ # After that, only a dynamic schedule can have changed while
68
+ # we were not master.
69
+ if dynamic || !schedule_loaded
70
+ reload_schedule!
71
+ schedule_loaded = true
72
+ end
66
73
  end
67
74
 
68
75
  if am_master
@@ -86,8 +93,8 @@ module Resque
86
93
  if rufus_scheduler
87
94
  log! "Scheduling Info\tLast Run"
88
95
  scheduler_jobs = rufus_scheduler.jobs
89
- scheduler_jobs.each do |_k, v|
90
- log! "#{v.t}\t#{v.last}\t"
96
+ scheduler_jobs.each do |job|
97
+ log! "#{job.opts}\t#{job.last_time}\t"
91
98
  end
92
99
  end
93
100
  end
@@ -148,8 +155,13 @@ module Resque
148
155
  args = optionizate_interval_value(config[interval_type])
149
156
  args = [args, nil, job: true] if args.is_a?(::String)
150
157
 
151
- job = rufus_scheduler.send(interval_type, *args) do
152
- enqueue_recurring(name, config)
158
+ begin
159
+ job = rufus_scheduler.send(interval_type, *args) do
160
+ enqueue_recurring(name, config)
161
+ end
162
+ rescue ArgumentError => e
163
+ log_error "Invalid #{interval_type} schedule for #{name}: #{e.message} - skipping"
164
+ return
153
165
  end
154
166
  @scheduled_jobs[name] = job
155
167
  interval_defined = true
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.license = 'MIT'
33
33
  spec.metadata['rubygems_mfa_required'] = 'true'
34
34
 
35
- spec.required_ruby_version = '>= 2.3.0'
35
+ spec.required_ruby_version = '>= 3.0.0'
36
36
 
37
37
  spec.files = `git ls-files -z`.split("\0").reject do |f|
38
38
  f.match(%r{^(test|spec|features|examples|bin|tasks)/}) ||
@@ -45,8 +45,10 @@ Gem::Specification.new do |spec|
45
45
 
46
46
  spec.add_development_dependency 'bundler'
47
47
  spec.add_development_dependency 'json'
48
+ spec.add_development_dependency 'irb'
48
49
  spec.add_development_dependency 'minitest'
49
50
  spec.add_development_dependency 'mocha'
51
+ spec.add_development_dependency 'ostruct'
50
52
  spec.add_development_dependency 'pry'
51
53
  spec.add_development_dependency 'rack-test'
52
54
  spec.add_development_dependency 'rake'
@@ -57,11 +59,13 @@ Gem::Specification.new do |spec|
57
59
 
58
60
  # We pin rubocop because new cops have a tendency to result in false-y
59
61
  # positives for new contributors, which is not a nice experience.
60
- spec.add_development_dependency 'rubocop', '~> 0.40.0'
62
+ spec.add_development_dependency 'rubocop', '~> 0.80'
61
63
 
64
+ spec.add_runtime_dependency 'base64', '~> 0.1'
65
+ spec.add_runtime_dependency 'logger'
62
66
  spec.add_runtime_dependency 'mono_logger', '~> 1.0'
63
- spec.add_runtime_dependency 'redis', '>= 3.3'
64
- spec.add_runtime_dependency 'resque', '>= 1.27'
67
+ spec.add_runtime_dependency 'redis', '>= 4.0'
68
+ spec.add_runtime_dependency 'resque', '>= 3.0'
65
69
  # rufus-scheduler v3.7 causes a failure in test/multi_process_test.rb
66
70
  # rufus-scheduler v3.3 is missing a to_local method which fails tests
67
71
  spec.add_runtime_dependency 'rufus-scheduler', '~> 3.2', '!= 3.3'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.11.0
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben VandenBos
@@ -10,10 +10,9 @@ authors:
10
10
  - Dan Buch
11
11
  - Michael Bianco
12
12
  - Patrick Tulskie
13
- autorequire:
14
13
  bindir: exe
15
14
  cert_chain: []
16
- date: 2024-12-30 00:00:00.000000000 Z
15
+ date: 1980-01-02 00:00:00.000000000 Z
17
16
  dependencies:
18
17
  - !ruby/object:Gem::Dependency
19
18
  name: bundler
@@ -43,6 +42,20 @@ dependencies:
43
42
  - - ">="
44
43
  - !ruby/object:Gem::Version
45
44
  version: '0'
45
+ - !ruby/object:Gem::Dependency
46
+ name: irb
47
+ requirement: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ type: :development
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
46
59
  - !ruby/object:Gem::Dependency
47
60
  name: minitest
48
61
  requirement: !ruby/object:Gem::Requirement
@@ -71,6 +84,20 @@ dependencies:
71
84
  - - ">="
72
85
  - !ruby/object:Gem::Version
73
86
  version: '0'
87
+ - !ruby/object:Gem::Dependency
88
+ name: ostruct
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ type: :development
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
74
101
  - !ruby/object:Gem::Dependency
75
102
  name: pry
76
103
  requirement: !ruby/object:Gem::Requirement
@@ -175,14 +202,42 @@ dependencies:
175
202
  requirements:
176
203
  - - "~>"
177
204
  - !ruby/object:Gem::Version
178
- version: 0.40.0
205
+ version: '0.80'
179
206
  type: :development
180
207
  prerelease: false
181
208
  version_requirements: !ruby/object:Gem::Requirement
182
209
  requirements:
183
210
  - - "~>"
184
211
  - !ruby/object:Gem::Version
185
- version: 0.40.0
212
+ version: '0.80'
213
+ - !ruby/object:Gem::Dependency
214
+ name: base64
215
+ requirement: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - "~>"
218
+ - !ruby/object:Gem::Version
219
+ version: '0.1'
220
+ type: :runtime
221
+ prerelease: false
222
+ version_requirements: !ruby/object:Gem::Requirement
223
+ requirements:
224
+ - - "~>"
225
+ - !ruby/object:Gem::Version
226
+ version: '0.1'
227
+ - !ruby/object:Gem::Dependency
228
+ name: logger
229
+ requirement: !ruby/object:Gem::Requirement
230
+ requirements:
231
+ - - ">="
232
+ - !ruby/object:Gem::Version
233
+ version: '0'
234
+ type: :runtime
235
+ prerelease: false
236
+ version_requirements: !ruby/object:Gem::Requirement
237
+ requirements:
238
+ - - ">="
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
186
241
  - !ruby/object:Gem::Dependency
187
242
  name: mono_logger
188
243
  requirement: !ruby/object:Gem::Requirement
@@ -203,28 +258,28 @@ dependencies:
203
258
  requirements:
204
259
  - - ">="
205
260
  - !ruby/object:Gem::Version
206
- version: '3.3'
261
+ version: '4.0'
207
262
  type: :runtime
208
263
  prerelease: false
209
264
  version_requirements: !ruby/object:Gem::Requirement
210
265
  requirements:
211
266
  - - ">="
212
267
  - !ruby/object:Gem::Version
213
- version: '3.3'
268
+ version: '4.0'
214
269
  - !ruby/object:Gem::Dependency
215
270
  name: resque
216
271
  requirement: !ruby/object:Gem::Requirement
217
272
  requirements:
218
273
  - - ">="
219
274
  - !ruby/object:Gem::Version
220
- version: '1.27'
275
+ version: '3.0'
221
276
  type: :runtime
222
277
  prerelease: false
223
278
  version_requirements: !ruby/object:Gem::Requirement
224
279
  requirements:
225
280
  - - ">="
226
281
  - !ruby/object:Gem::Version
227
- version: '1.27'
282
+ version: '3.0'
228
283
  - !ruby/object:Gem::Dependency
229
284
  name: rufus-scheduler
230
285
  requirement: !ruby/object:Gem::Requirement
@@ -261,8 +316,11 @@ executables:
261
316
  extensions: []
262
317
  extra_rdoc_files: []
263
318
  files:
319
+ - ".devcontainer/Dockerfile"
320
+ - ".devcontainer/README.md"
321
+ - ".devcontainer/devcontainer.json"
322
+ - ".devcontainer/docker-compose.yml"
264
323
  - ".github/dependabot.yml"
265
- - ".github/funding.yml"
266
324
  - ".github/workflows/codeql-analysis.yml"
267
325
  - ".github/workflows/rubocop.yml"
268
326
  - ".github/workflows/ruby.yml"
@@ -309,7 +367,6 @@ licenses:
309
367
  - MIT
310
368
  metadata:
311
369
  rubygems_mfa_required: 'true'
312
- post_install_message:
313
370
  rdoc_options: []
314
371
  require_paths:
315
372
  - lib
@@ -317,15 +374,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
317
374
  requirements:
318
375
  - - ">="
319
376
  - !ruby/object:Gem::Version
320
- version: 2.3.0
377
+ version: 3.0.0
321
378
  required_rubygems_version: !ruby/object:Gem::Requirement
322
379
  requirements:
323
380
  - - ">="
324
381
  - !ruby/object:Gem::Version
325
382
  version: '0'
326
383
  requirements: []
327
- rubygems_version: 3.0.3.1
328
- signing_key:
384
+ rubygems_version: 4.0.16
329
385
  specification_version: 4
330
386
  summary: Light weight job scheduling on top of Resque
331
387
  test_files: []
data/.github/funding.yml DELETED
@@ -1,4 +0,0 @@
1
- # Docs for this file can be found here:
2
- # https://docs.github.com/en/github/administering-a-repository/displaying-a-sponsor-button-in-your-repository
3
-
4
- github: ["iloveitaly"]