que-scheduler 3.4.3 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ba02202915db229bcbd1c2e859f29299803507dbf61bd460008400abca3611c
4
- data.tar.gz: 6293d7b6e6766d0e75fe65df01850f356b44b030c8b8ae539eb4c71059d9d15d
3
+ metadata.gz: f6250ff590c3c280c0219d93ba57f85758a993fba1185d2064f1ba714c8c9e4c
4
+ data.tar.gz: cb49ce9c63314888e05f48cc7cd5a98817deb0df03763b9aae756055261acdbb
5
5
  SHA512:
6
- metadata.gz: d8d18550867d7d54cfb5c03aaa68876d423876a870b972cde0fbc4e8399fb616d327ef0410ebbc8e3d9021a34d73a960774eabb808f2b33a526e11ea2fb579fe
7
- data.tar.gz: bfc0e4be1f64d2b070dacb0863cc710ce13cf58cb30924fcf9f301d2e535be4ef9530740949bdb5abb90c0173924e71f7f151e4622405caf8c14a9d7d6f0469d
6
+ metadata.gz: 9516e812e2d394d5ff7c23641db0344a34c3560ad4ed02a114cc9820beee8202da9416450fbfc68f92bfaa6aed4f5bf16d1df3d2476f487a58f6f0fb32141aa1
7
+ data.tar.gz: 4d29b9a9161713935ccf1dcea71303195131fa8c27570b05a528fdec68d146b72c316ebeed523fabecda625c0128e4accca76ba0f47ba63fb8ff1d6106c96120
data/README.md CHANGED
@@ -28,7 +28,7 @@ resque-scheduler files, but with additional features.
28
28
  ```ruby
29
29
  class CreateQueSchedulerSchema < ActiveRecord::Migration
30
30
  def change
31
- Que::Scheduler::Migrations.migrate!(version: 5)
31
+ Que::Scheduler::Migrations.migrate!(version: 6)
32
32
  end
33
33
  end
34
34
  ```
@@ -160,8 +160,11 @@ Additionally, there is the audit table `que_scheduler_audit_enqueued`. This logs
160
160
  the scheduler enqueues.
161
161
 
162
162
  When there is a major version (breaking) change, a migration should be run in. The version of the
163
- migration proceeds at a faster rate than the version of the gem. To run in all the migrations required
164
- up to a number, just migrate to that number with one line, and it will perform all the intermediary steps.
163
+ latest migration proceeds at a faster rate than the version of the gem, eg if the gem is on version
164
+ 3 then the migrations may be on version 6).
165
+
166
+ To run in all the migrations required up to a number, just migrate to that number with one line, and
167
+ it will perform all the intermediary steps.
165
168
 
166
169
  ie, This will perform all migrations necessary up to the latest version, skipping any already
167
170
  performed.
@@ -169,7 +172,7 @@ performed.
169
172
  ```ruby
170
173
  class CreateQueSchedulerSchema < ActiveRecord::Migration
171
174
  def change
172
- Que::Scheduler::Migrations.migrate!(version: 5)
175
+ Que::Scheduler::Migrations.migrate!(version: 6)
173
176
  end
174
177
  end
175
178
  ```
@@ -183,6 +186,7 @@ The changes in past migrations were:
183
186
  | 3 | Added the audit table `que_scheduler_audit_enqueued`. |
184
187
  | 4 | Updated the the audit tables to use bigints |
185
188
  | 5 | Dropped an unnecessary index |
189
+ | 6 | Enforced single scheduler job at the trigger level |
186
190
 
187
191
  ## Built in optional job for audit clear down
188
192
 
@@ -214,8 +218,8 @@ in a coherent state with the rest of your database.
214
218
  ## Concurrent scheduler detection
215
219
 
216
220
  No matter how many tasks you have defined in your schedule, you will only ever need one que-scheduler
217
- job enqueued. que-scheduler knows this, and it will check before performing any operations that
218
- there is only one of itself present.
221
+ job enqueued. que-scheduler knows this, and there are DB constraints in place to ensure there is
222
+ only ever exactly one scheduler job.
219
223
 
220
224
  It also follows que job design [best practices](https://github.com/chanks/que/blob/master/docs/writing_reliable_jobs.md),
221
225
  using ACID guarantees, to ensure that it will never run multiple times. If the scheduler crashes for any reason,
@@ -267,6 +271,10 @@ The scheduler will then continue to retry indefinitely.
267
271
  que-scheduler uses [semantic versioning](https://semver.org/), so major version changes will usually
268
272
  require additional actions to be taken upgrading from one major version to another.
269
273
 
274
+ ## Changelog
275
+
276
+ A full changelog can be found here: [CHANGELOG.md](https://github.com/hlascelles/que-scheduler/blob/master/CHANGELOG.md)
277
+
270
278
  ## System requirements
271
279
 
272
280
  Your [postgres](https://www.postgresql.org/) database must be at least version 9.4.0.
@@ -277,9 +285,9 @@ This gem was inspired by the makers of the excellent [Que](https://github.com/ch
277
285
 
278
286
  ## Contributors
279
287
 
288
+ * @bnauta
289
+ * @JackDanger
280
290
  * @jish
281
291
  * @joehorsnell
282
- * @bnauta
283
- * @papodaca
284
292
  * @krzyzak
285
- * @JackDanger
293
+ * @papodaca
@@ -0,0 +1,7 @@
1
+ DROP TRIGGER que_scheduler_prevent_job_deletion_trigger ON que_jobs;
2
+
3
+ DROP FUNCTION que_scheduler_prevent_job_deletion();
4
+
5
+ DROP FUNCTION que_scheduler_check_job_exists();
6
+
7
+ DROP INDEX que_scheduler_job_in_que_jobs_unique_index;
@@ -0,0 +1,26 @@
1
+ -- Ensure there is no more than one scheduler
2
+ CREATE UNIQUE INDEX que_scheduler_job_in_que_jobs_unique_index ON que_jobs(job_class)
3
+ WHERE job_class = 'Que::Scheduler::SchedulerJob';
4
+
5
+ -- Ensure there is at least one scheduler
6
+ CREATE OR REPLACE FUNCTION que_scheduler_check_job_exists() RETURNS bool AS $$
7
+ SELECT EXISTS(SELECT * FROM que_jobs WHERE job_class = 'Que::Scheduler::SchedulerJob');
8
+ $$ LANGUAGE SQL;
9
+
10
+ CREATE OR REPLACE FUNCTION que_scheduler_prevent_job_deletion() RETURNS TRIGGER AS
11
+ $BODY$
12
+ DECLARE
13
+ BEGIN
14
+ IF OLD.job_class = 'Que::Scheduler::SchedulerJob' THEN
15
+ IF NOT que_scheduler_check_job_exists() THEN
16
+ raise exception 'Deletion of que_scheduler job % prevented. Deleting the que_scheduler job is almost certainly a mistake.', OLD.job_id;
17
+ END IF;
18
+ END IF;
19
+ RETURN OLD;
20
+ END;
21
+ $BODY$
22
+ LANGUAGE 'plpgsql';
23
+
24
+ CREATE CONSTRAINT TRIGGER que_scheduler_prevent_job_deletion_trigger AFTER UPDATE OR DELETE ON que_jobs
25
+ DEFERRABLE INITIALLY DEFERRED
26
+ FOR EACH ROW EXECUTE PROCEDURE que_scheduler_prevent_job_deletion();
@@ -16,8 +16,8 @@ module Que
16
16
  class SchedulerJob < Que::Job
17
17
  SCHEDULER_FREQUENCY = 60
18
18
 
19
- Que::Scheduler::VersionSupport.set_priority(self, 0)
20
- Que::Scheduler::VersionSupport.apply_retry_semantics(self)
19
+ VersionSupport.set_priority(self, 0)
20
+ VersionSupport.apply_retry_semantics(self)
21
21
 
22
22
  def run(options = nil)
23
23
  Que::Scheduler::Db.transaction do
@@ -27,12 +27,13 @@ module Que
27
27
  logs = ["que-scheduler last ran at #{scheduler_job_args.last_run_time}."]
28
28
  result = EnqueueingCalculator.parse(Scheduler.schedule.values, scheduler_job_args)
29
29
  enqueued_jobs = enqueue_required_jobs(result, logs)
30
+ # Remove this job and schedule self again
31
+ destroy
30
32
  enqueue_self_again(
31
33
  scheduler_job_args, scheduler_job_args.as_time, result.job_dictionary, enqueued_jobs
32
34
  )
33
35
  # Only now we're sure nothing errored, log the results
34
36
  logs.each { |str| ::Que.log(event: "que-scheduler".to_sym, message: str) }
35
- destroy
36
37
  end
37
38
  end
38
39
 
@@ -59,7 +60,7 @@ module Que
59
60
 
60
61
  def enqueue_self_again(scheduler_job_args, last_full_execution, job_dictionary, enqueued_jobs)
61
62
  # Log last run...
62
- job_id = Que::Scheduler::VersionSupport.job_attributes(self).fetch(:job_id)
63
+ job_id = VersionSupport.job_attributes(self).fetch(:job_id)
63
64
  Audit.append(job_id, scheduler_job_args.as_time, enqueued_jobs)
64
65
 
65
66
  # And rerun...
@@ -72,7 +73,7 @@ module Que
72
73
  )
73
74
 
74
75
  # rubocop:disable Style/GuardClause This reads better as a conditional
75
- unless Que::Scheduler::VersionSupport.job_attributes(enqueued_job).fetch(:job_id)
76
+ unless enqueued_job && VersionSupport.job_attributes(enqueued_job).fetch(:job_id)
76
77
  raise "SchedulerJob could not self-schedule. Has `.enqueue` been monkey patched?"
77
78
  end
78
79
  # rubocop:enable Style/GuardClause
@@ -8,7 +8,6 @@ module Que
8
8
  class << self
9
9
  def check
10
10
  assert_db_migrated
11
- assert_one_scheduler_job
12
11
  end
13
12
 
14
13
  private
@@ -60,21 +59,6 @@ module Que
60
59
  synchronously. This will fail as que-scheduler needs the above tables to work.
61
60
  ERR
62
61
  end
63
-
64
- def assert_one_scheduler_job
65
- schedulers = Que::Scheduler::Db.count_schedulers
66
- return if schedulers == 1
67
-
68
- raise(<<-ERR)
69
- Only one #{Que::Scheduler::SchedulerJob.name} should be enqueued. #{schedulers} were found.
70
-
71
- que-scheduler works by running a self-enqueueing version of itself that determines which
72
- jobs should be enqueued based on the provided config. If two or more que-schedulers were
73
- to run at once, then duplicate jobs would occur.
74
-
75
- To resolve this problem, please remove any duplicate scheduler jobs from the que_jobs table.
76
- ERR
77
- end
78
62
  end
79
63
  end
80
64
  end
@@ -1,5 +1,5 @@
1
1
  module Que
2
2
  module Scheduler
3
- VERSION = "3.4.3".freeze
3
+ VERSION = "4.0.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: que-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.3
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harry Lascelles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-28 00:00:00.000000000 Z
11
+ date: 2020-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -335,6 +335,8 @@ files:
335
335
  - lib/que/scheduler/migrations/4/up.sql
336
336
  - lib/que/scheduler/migrations/5/down.sql
337
337
  - lib/que/scheduler/migrations/5/up.sql
338
+ - lib/que/scheduler/migrations/6/down.sql
339
+ - lib/que/scheduler/migrations/6/up.sql
338
340
  - lib/que/scheduler/schedule.rb
339
341
  - lib/que/scheduler/scheduler_job.rb
340
342
  - lib/que/scheduler/scheduler_job_args.rb