rufus-scheduler 3.8.2 → 3.9.1

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: 9fbe0f73068129b96196031b141f480f830e3110e35d3c5eaa2206530b1ae536
4
- data.tar.gz: bec310a43820928b8d342b5b3602edf8cb27aaca8995e0a18073d70dfd3839f8
3
+ metadata.gz: a9db2ffb7b6d057285e7e5fe94a8d984931d59dcad6c73ddb4375888d23f67ce
4
+ data.tar.gz: 30a77e6df03c57cbebb532490f7c4162bc46a071f12eb55cab1d4e4a2a6f6f46
5
5
  SHA512:
6
- metadata.gz: 3e8edfd4df2ddbb0f8026ffa13fff69f9f4bd045da1638fe5ac38610992e0f7d173b20a27ad1833760d6fee62d41b5b160978e107dbc55a1b9d07dfaa62444ad
7
- data.tar.gz: 412bb7e80546c5cd13bf8875f928ce6920a9e62774d296db83935adbfee56069cbb2729bb4640962351297cd55b8b5cfb92facfec38e7cb92b3ef9f7446c7283
6
+ metadata.gz: 8a70f7d30cc73d68ad64ad2d774dc2422fc74487aa655ec8f1c97b465db07e243592015ff3d62f01354b5541fe611b3a505a5e90529048226305de7f800bba98
7
+ data.tar.gz: 6d5df01c2f1f0da7502fb82f81ec25d17f90c8c04eaf6f15fc389d9471145ba9ef30da50e2377744c7bb367fb5d4aeda469e8b8548b45894abd72a4ccb65d857
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
+ ### rufus-scheduler 3.9.1 - released 2023-06-09
6
+
7
+ * Introduce :first_at_no_error option, austinarbor gh-342
8
+
9
+
10
+ ### rufus-scheduler 3.9.0 - released 2023-06-02
11
+
12
+ * Add note about Chronic and "Wed at 2pm", gh-340
13
+ * Let AtJob and InJob accept discard_past:
14
+ * Enforce discard_past for At and In jobs, gh-339
15
+
16
+
5
17
  ### rufus-scheduler 3.8.2 - released 2022-07-12
6
18
 
7
19
  * Prevent error in shutdown when @thread is current Thread, gh-337
data/CREDITS.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  ## Contributors
6
6
 
7
+ * Austin Arbor https://github.com/austinarbor gh-342 first_at_error
7
8
  * Bence Monus https://github.com/cromega gh-337 on_error and friends
8
9
  * Talia Wong https://github.com/blowfishpro gh-335 on_error and friends
9
10
  * Konstantin https://github.com/fa11enangel gh-334 nodejitsu link
@@ -72,6 +73,7 @@
72
73
 
73
74
  ## Feedback
74
75
 
76
+ * jasonwbarnett (https://github.com/jaswonwbarnett) past time jobs, gh-339
75
77
  * aphel (https://github.com/itsaphel) #shutdown vs current thread, gh-304
76
78
  * aesyondu (https://github.com/aesyondu) Rails console 4.2.x, gh-186
77
79
  * Sasha Hoellger (https://github.com/mitnal) parse_cron and readme, gh-270
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2005-2022, John Mettraux, jmettraux@gmail.com
2
+ Copyright (c) 2005-2023, John Mettraux, jmettraux@gmail.com
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
data/Makefile CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
- NAME = \
3
- $(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.name")
4
- VERSION = \
5
- $(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.version")
2
+ NAME != \
3
+ ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.name"
4
+ VERSION != \
5
+ ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.version"
6
6
 
7
7
  count_lines:
8
8
  find lib -name "*.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
data/README.md CHANGED
@@ -3,7 +3,6 @@
3
3
 
4
4
  [![tests](https://github.com/jmettraux/rufus-scheduler/workflows/test/badge.svg)](https://github.com/jmettraux/rufus-scheduler/actions)
5
5
  [![Gem Version](https://badge.fury.io/rb/rufus-scheduler.svg)](https://badge.fury.io/rb/rufus-scheduler)
6
- [![Join the chat at https://gitter.im/floraison/fugit](https://badges.gitter.im/floraison/fugit.svg)](https://gitter.im/floraison/fugit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7
6
 
8
7
  Job scheduler for Ruby (at, cron, in and every jobs).
9
8
 
@@ -106,7 +105,7 @@ I'll drive you right to the [tracks](#so-rails).
106
105
  * Rufus::Scheduler::TimeOutError renamed to Rufus::Scheduler::TimeoutError
107
106
  * Introduction of "interval" jobs. Whereas "every" jobs are like "every 10 minutes, do this", interval jobs are like "do that, then wait for 10 minutes, then do that again, and so on"
108
107
  * Introduction of a lockfile: true/filename mechanism to prevent multiple schedulers from executing
109
- * "discard_past" is on by default. If the scheduler (its host) sleeps for 1 hour and a `every '10m'` job is on, it will trigger once at wakeup, not 6 times (discard_past was false by default in rufus-scheduler 2.x). No intention to re-introduce `discard_past: false` in 3.0 for now.
108
+ * "discard_past" is on by default. If the scheduler (its host) sleeps for 1 hour and a `every '10m'` job is on, it will trigger once at wakeup, not 6 times (discard_past was false by default in rufus-scheduler 2.x).
110
109
  * Introduction of Scheduler #on_pre_trigger and #on_post_trigger callback points
111
110
 
112
111
 
@@ -120,12 +119,6 @@ Go read [how to report bugs effectively](https://www.chiark.greenend.org.uk/~sgt
120
119
 
121
120
  Update: [help_help.md](https://gist.github.com/jmettraux/310fed75f568fd731814) might help help you.
122
121
 
123
- ### on Gitter
124
-
125
- You can find help via chat over at [https://gitter.im/floraison/fugit](https://gitter.im/floraison/fugit). It's [fugit](https://github.com/floraison/fugit), [et-orbi](https://github.com/floraison/et-orbi), and rufus-scheduler combined chat room.
126
-
127
- Please be courteous.
128
-
129
122
  ### issues
130
123
 
131
124
  Yes, issues can be reported in [rufus-scheduler issues](https://github.com/jmettraux/rufus-scheduler/issues), I'd actually prefer bugs in there. If there is nothing wrong with rufus-scheduler, a [Stack Overflow question](https://stackoverflow.com/questions/ask?tags=rufus-scheduler+ruby) is better.
@@ -198,7 +191,34 @@ Interval jobs trigger, execute and then trigger again after the interval elapsed
198
191
 
199
192
  Cron jobs are based on the venerable cron utility (```man 5 crontab```). They trigger following a pattern given in (almost) the same language cron uses.
200
193
 
201
- ####
194
+ ### Chronic and "Wed at 2pm"
195
+
196
+ By default, rufus-scheduler relies on Ruby to parse strings like "Wed at 2pm". But most of the time, when calling this on Thursday, the day before is "invoked". Relying on [Chronic](https://github.com/mojombo/chronic) might solve the issue.
197
+
198
+ Compare
199
+
200
+ ```ruby
201
+ require 'rufus-scheduler'
202
+
203
+ scheduler = Rufus::Scheduler.new
204
+
205
+ scheduler.at('Wed at 2pm') do
206
+ # ... might point in the past and thus get triggered immediately
207
+ end
208
+ ```
209
+
210
+ with
211
+
212
+ ```ruby
213
+ require 'chronic'
214
+ require 'rufus-scheduler'
215
+
216
+ scheduler = Rufus::Scheduler.new
217
+
218
+ scheduler.at('Wed at 2pm') do
219
+ # ... will point to a time in the future and trigger appropriately
220
+ end
221
+ ```
202
222
 
203
223
  ### #schedule_x vs #x
204
224
 
@@ -495,6 +515,18 @@ that'll output something like:
495
515
  ...
496
516
  ```
497
517
 
518
+ ### :first_at_no_error
519
+
520
+ In some heavy-duty configurations, the `:first_at` setting might be set on a point of time before the actual scheduling/triggering occurs and will result in an error `"cannot set first[_at|_in] in the past..."`. To prevent that, the `:first_at_no_error` option may be set to true.
521
+
522
+ ```ruby
523
+ scheduler.every '10h', first_at: Time.now + 10, first_at_no_error: true do
524
+ # ...
525
+ end
526
+ ```
527
+
528
+ As introduced in [gh-342](https://github.com/jmettraux/rufus-scheduler/pull/342).
529
+
498
530
  ### :last_at, :last_in, :last
499
531
 
500
532
  This option is for repeat jobs (cron / every) only.
@@ -561,6 +593,43 @@ job.times = 10
561
593
  # 10 days and it will be over
562
594
  ```
563
595
 
596
+ ### discard_past: false/true/:fail
597
+
598
+ `in` and `at` accept a `discard_past:` option since rufus-scheduler 3.9.0:
599
+
600
+ ```ruby
601
+ require 'rufus-scheduler'
602
+
603
+ scheduler = Rufus::Scheduler.new
604
+
605
+ scheduler.in(-3600, discard_past: true) {}
606
+ # the job will never get scheduled
607
+
608
+ scheduler.in(-3600, discard_past: false) {}
609
+ # the job will trigger immediately
610
+
611
+ scheduler.in(-3600, discard_past: :fail) {}
612
+ # will raise an error...
613
+ ```
614
+
615
+ Please note that `discard_past` can be set at the scheduler level:
616
+
617
+ ```ruby
618
+ require 'rufus-scheduler'
619
+
620
+ s0 = Rufus::Scheduler.new(discard_past: true) # default
621
+
622
+ s1 = Rufus::Scheduler.new(discard_past: false)
623
+ # or
624
+ s1 = Rufus::Scheduler.new
625
+ s1.discard_past = false
626
+
627
+ s2 = Rufus::Scheduler.new(discard_past: :fail)
628
+ # or
629
+ s2 = Rufus::Scheduler.new
630
+ s2.discard_past = :fail
631
+ ```
632
+
564
633
 
565
634
  ## Job methods
566
635
 
@@ -1589,6 +1658,26 @@ require 'tzinfo/data'
1589
1658
  require 'rufus-scheduler'
1590
1659
  ```
1591
1660
 
1661
+ ### Timezone in the schedule thread
1662
+
1663
+ Currently (3.9.x), rufus-scheduler strives to trigger at the right time. The trigger thread might not yield a `Time.now` in the scheduled timezone.
1664
+
1665
+ ```ruby
1666
+ ENV['TZ'] = 'Asia/Tokyo'
1667
+
1668
+ require 'rufus-scheduler'
1669
+
1670
+ s = Rufus::Scheduler.new
1671
+
1672
+ s.cron('*/5 * * * * * Europe/Rome') do
1673
+ p Time.now # ==> the representation will indicate the time is UTC+0900...
1674
+ end
1675
+
1676
+ s.join
1677
+ ```
1678
+
1679
+ In the wake of [gh-341](https://github.com/jmettraux/rufus-scheduler/issues/341).
1680
+
1592
1681
 
1593
1682
  ## so Rails?
1594
1683
 
@@ -67,6 +67,8 @@ class Rufus::Scheduler::Job
67
67
  @unscheduled_at = nil
68
68
  @last_time = nil
69
69
 
70
+ @discard_past = opts[:discard_past]
71
+
70
72
  @locals = opts[:locals] || opts[:l] || {}
71
73
  @local_mutex = Mutex.new
72
74
 
@@ -74,9 +76,7 @@ class Rufus::Scheduler::Job
74
76
  @name = opts[:name] || opts[:n]
75
77
 
76
78
  fail(
77
- ArgumentError,
78
- 'missing block or callable to schedule',
79
- caller[2..-1]
79
+ ArgumentError, 'missing block or callable to schedule', caller[2..-1]
80
80
  ) unless @callable
81
81
 
82
82
  @tags = Array(opts[:tag] || opts[:tags]).collect { |t| t.to_s }
@@ -103,6 +103,14 @@ class Rufus::Scheduler::Job
103
103
  end
104
104
  alias location source_location
105
105
 
106
+ # Returns true if the job is scheduled in the past.
107
+ # Used for OneTimeJob when discard_past == true
108
+ #
109
+ def past?
110
+
111
+ false # by default
112
+ end
113
+
106
114
  # Will fail with an ArgumentError if the job frequency is higher than
107
115
  # the scheduler frequency.
108
116
  #
@@ -365,5 +373,16 @@ class Rufus::Scheduler::Job
365
373
 
366
374
  @scheduler.work_queue << [ self, time ]
367
375
  end
376
+
377
+ # Scheduler level < Job level < this resume()'s level
378
+ #
379
+ def discard_past?
380
+
381
+ dp = @scheduler.discard_past
382
+ dp = @discard_past if @discard_past != nil
383
+ dp = @resume_discard_past if @resume_discard_past != nil
384
+
385
+ dp
386
+ end
368
387
  end
369
388
 
@@ -8,6 +8,14 @@ class Rufus::Scheduler::OneTimeJob < Rufus::Scheduler::Job
8
8
  (time >= time0 && time <= time1) ? [ time ] : []
9
9
  end
10
10
 
11
+ # Used when discard_past? is set to true or :fail at scheduler or job level...
12
+ #
13
+ def past?
14
+
15
+ @next_time &&
16
+ @next_time < Time.now - @scheduler.frequency
17
+ end
18
+
11
19
  protected
12
20
 
13
21
  def determine_id
@@ -20,7 +28,7 @@ class Rufus::Scheduler::OneTimeJob < Rufus::Scheduler::Job
20
28
  ].map(&:to_s).join('_')
21
29
  end
22
30
 
23
- # There is no next_time for one time jobs, hence the false.
31
+ # There is no "next time" for one time jobs, hence the false.
24
32
  #
25
33
  def set_next_time(trigger_time, is_post=false, now=nil)
26
34
 
@@ -15,6 +15,8 @@ class Rufus::Scheduler::RepeatJob < Rufus::Scheduler::Job
15
15
 
16
16
  @times = opts[:times]
17
17
 
18
+ @first_at_no_error = opts[:first_at_no_error] || false
19
+
18
20
  fail ArgumentError.new(
19
21
  "cannot accept :times => #{@times.inspect}, not nil or an int"
20
22
  ) unless @times == nil || @times.is_a?(Integer)
@@ -43,6 +45,7 @@ class Rufus::Scheduler::RepeatJob < Rufus::Scheduler::Job
43
45
 
44
46
  @first_at = (fdur && (EoTime.now + fdur)) || EoTime.make(first)
45
47
  @first_at = n1 if @first_at >= n0 && @first_at < n1
48
+ @first_at = n0 if @first_at < n0 && @first_at_no_error
46
49
 
47
50
  fail ArgumentError.new(
48
51
  "cannot set first[_at|_in] in the past: " +
@@ -93,7 +96,6 @@ class Rufus::Scheduler::RepeatJob < Rufus::Scheduler::Job
93
96
  def resume(opts={})
94
97
 
95
98
  @resume_discard_past = opts[:discard_past]
96
- #p [ :@resume_discard_past, @resume_discard_past ]
97
99
  @paused_at = nil
98
100
  end
99
101
 
@@ -145,17 +147,6 @@ class Rufus::Scheduler::RepeatJob < Rufus::Scheduler::Job
145
147
  a << next_time_from(a.last)
146
148
  a }
147
149
  end
148
-
149
- protected
150
-
151
- def discard_past?
152
-
153
- dp = @scheduler.discard_past
154
- dp = @discard_past if @discard_past != nil
155
- dp = @resume_discard_past if @resume_discard_past != nil
156
-
157
- dp
158
- end
159
150
  end
160
151
 
161
152
  #
@@ -180,7 +171,6 @@ class Rufus::Scheduler::EveryJob < Rufus::Scheduler::EvInJob
180
171
  super(scheduler, duration, opts, block)
181
172
 
182
173
  @frequency = Rufus::Scheduler.parse_in(@original)
183
- @discard_past = opts[:discard_past]
184
174
 
185
175
  fail ArgumentError.new(
186
176
  "cannot schedule #{self.class} with a frequency " +
@@ -332,4 +322,3 @@ class Rufus::Scheduler::CronJob < Rufus::Scheduler::RepeatJob
332
322
  end
333
323
  end
334
324
  end
335
-
@@ -9,7 +9,7 @@ module Rufus; end
9
9
 
10
10
  class Rufus::Scheduler
11
11
 
12
- VERSION = '3.8.2'
12
+ VERSION = '3.9.1'
13
13
 
14
14
  EoTime = ::EtOrbi::EoTime
15
15
 
@@ -722,6 +722,14 @@ class Rufus::Scheduler
722
722
  end
723
723
 
724
724
  job = job_class.new(self, t, opts, block || callable)
725
+
726
+ if job.past? && (d = job.send(:discard_past?))
727
+ fail ArgumentError.new(
728
+ "scheduling in the past and discard_past set to :fail"
729
+ ) if d == :fail
730
+ return
731
+ end
732
+
725
733
  job.check_frequency
726
734
 
727
735
  @jobs.push(job)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufus-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.8.2
4
+ version: 3.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-12 00:00:00.000000000 Z
11
+ date: 2023-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fugit
@@ -88,7 +88,7 @@ metadata:
88
88
  bug_tracker_uri: https://github.com/jmettraux/rufus-scheduler/issues
89
89
  homepage_uri: https://github.com/jmettraux/rufus-scheduler
90
90
  source_code_uri: https://github.com/jmettraux/rufus-scheduler
91
- post_install_message:
91
+ post_install_message:
92
92
  rdoc_options: []
93
93
  require_paths:
94
94
  - lib
@@ -103,8 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  requirements: []
106
- rubygems_version: 3.0.3
107
- signing_key:
106
+ rubygems_version: 3.2.33
107
+ signing_key:
108
108
  specification_version: 4
109
109
  summary: job scheduler for Ruby (at, cron, in and every jobs)
110
110
  test_files: []