openwferu-scheduler 0.9.15.1110 → 0.9.15.1127
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/openwfe/util/scheduler.rb +135 -62
- metadata +2 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
#--
|
3
3
|
# Copyright (c) 2006-2007, John Mettraux, OpenWFE.org
|
4
4
|
# All rights reserved.
|
@@ -102,8 +102,7 @@ module OpenWFE
|
|
102
102
|
# This attribute is best used indirectly : the method
|
103
103
|
# join_until_no_more_jobs() wraps it.
|
104
104
|
#
|
105
|
-
#
|
106
|
-
# instantiating the scheduler.
|
105
|
+
# The :scheduler_precision can be set when instantiating the scheduler.
|
107
106
|
#
|
108
107
|
# scheduler = OpenWFE::Scheduler.new(:scheduler_precision => 0.500)
|
109
108
|
# scheduler.start
|
@@ -111,6 +110,29 @@ module OpenWFE
|
|
111
110
|
# # instatiates a scheduler that checks its jobs twice per second
|
112
111
|
# # (the default is 4 times per second (0.250))
|
113
112
|
#
|
113
|
+
#
|
114
|
+
# Since OpenWFEru 0.9.16, tags can be attached to jobs scheduled :
|
115
|
+
#
|
116
|
+
# scheduler.schedule_in "2h", :tags => "backup" do
|
117
|
+
# init_backup_sequence()
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
# scheduler.schedule "0 24 * * *", :tags => "new_day" do
|
121
|
+
# do_this_or_that()
|
122
|
+
# end
|
123
|
+
#
|
124
|
+
# jobs = find_jobs 'backup'
|
125
|
+
#
|
126
|
+
# Multiple tags may be attached to a single job :
|
127
|
+
#
|
128
|
+
# scheduler.schedule_in "2h", :tags => [ "backup", "important" ] do
|
129
|
+
# init_backup_sequence()
|
130
|
+
# end
|
131
|
+
#
|
132
|
+
# The vanilla case for tags assume they are String instances, but nothing
|
133
|
+
# prevents you from using anything else. The scheduler has no persistence
|
134
|
+
# by itself, so no serialization issue.
|
135
|
+
#
|
114
136
|
class Scheduler
|
115
137
|
include MonitorMixin
|
116
138
|
|
@@ -131,7 +153,7 @@ module OpenWFE
|
|
131
153
|
super()
|
132
154
|
|
133
155
|
@pending_jobs = []
|
134
|
-
@
|
156
|
+
@cron_jobs = {}
|
135
157
|
|
136
158
|
@scheduler_thread = nil
|
137
159
|
|
@@ -161,8 +183,11 @@ module OpenWFE
|
|
161
183
|
@scheduler_thread = Thread.new do
|
162
184
|
|
163
185
|
if defined?(JRUBY_VERSION)
|
186
|
+
|
164
187
|
require 'java'
|
165
|
-
|
188
|
+
|
189
|
+
java.lang.Thread.current_thread.name = \
|
190
|
+
"openwferu scheduler (Ruby Thread)"
|
166
191
|
end
|
167
192
|
|
168
193
|
while true
|
@@ -298,7 +323,7 @@ module OpenWFE
|
|
298
323
|
synchronize do
|
299
324
|
|
300
325
|
for i in 0...@pending_jobs.length
|
301
|
-
if @pending_jobs[i].
|
326
|
+
if @pending_jobs[i].job_id == job_id
|
302
327
|
@pending_jobs.delete_at i
|
303
328
|
return true
|
304
329
|
end
|
@@ -313,8 +338,8 @@ module OpenWFE
|
|
313
338
|
#
|
314
339
|
def unschedule_cron_job (job_id)
|
315
340
|
synchronize do
|
316
|
-
if @
|
317
|
-
@
|
341
|
+
if @cron_jobs.has_key?(job_id)
|
342
|
+
@cron_jobs.delete job_id
|
318
343
|
return true
|
319
344
|
end
|
320
345
|
false
|
@@ -359,28 +384,30 @@ module OpenWFE
|
|
359
384
|
|
360
385
|
unschedule(cron_id) if cron_id
|
361
386
|
|
387
|
+
tags = params[:tags]
|
388
|
+
|
362
389
|
#
|
363
390
|
# schedule
|
364
391
|
|
365
392
|
b = to_block(params, &block)
|
366
|
-
|
367
|
-
@
|
393
|
+
job = CronJob.new(cron_id, cron_line, tags, &b)
|
394
|
+
@cron_jobs[job.job_id] = job
|
368
395
|
|
369
|
-
|
396
|
+
job.job_id
|
370
397
|
end
|
371
398
|
end
|
372
399
|
|
373
400
|
#
|
374
|
-
# Returns the job corresponding to job_id, an instance of
|
375
|
-
# or
|
401
|
+
# Returns the job corresponding to job_id, an instance of AtJob
|
402
|
+
# or CronJob will be returned.
|
376
403
|
#
|
377
404
|
def get_job (job_id)
|
378
405
|
|
379
|
-
|
380
|
-
return
|
406
|
+
job = @cron_jobs[job_id]
|
407
|
+
return job if job
|
381
408
|
|
382
|
-
@pending_jobs.find do |
|
383
|
-
|
409
|
+
@pending_jobs.find do |job|
|
410
|
+
job.job_id == job_id
|
384
411
|
end
|
385
412
|
end
|
386
413
|
|
@@ -394,11 +421,44 @@ module OpenWFE
|
|
394
421
|
|
395
422
|
j = get_job(job_id)
|
396
423
|
|
397
|
-
return j.schedulable if j.respond_to?
|
424
|
+
return j.schedulable if j.respond_to?(:schedulable)
|
398
425
|
|
399
426
|
nil
|
400
427
|
end
|
401
428
|
|
429
|
+
#
|
430
|
+
# Returns an array of jobs that have the given tag.
|
431
|
+
#
|
432
|
+
def find_jobs (tag)
|
433
|
+
|
434
|
+
result = @cron_jobs.values.find_all do |job|
|
435
|
+
job.has_tag?(tag)
|
436
|
+
end
|
437
|
+
|
438
|
+
result + @pending_jobs.find_all do |job|
|
439
|
+
job.has_tag?(tag)
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
#
|
444
|
+
# Finds the jobs with the given tag and then returns an array of
|
445
|
+
# the wrapped Schedulable objects.
|
446
|
+
# Jobs that haven't a wrapped Schedulable won't be included in the
|
447
|
+
# result.
|
448
|
+
#
|
449
|
+
def find_schedulables (tag)
|
450
|
+
|
451
|
+
jobs = find_jobs(tag)
|
452
|
+
|
453
|
+
result = []
|
454
|
+
|
455
|
+
jobs.each do |job|
|
456
|
+
result.push(job.schedulable) if job.respond_to?(:schedulable)
|
457
|
+
end
|
458
|
+
|
459
|
+
result
|
460
|
+
end
|
461
|
+
|
402
462
|
#
|
403
463
|
# Returns the number of currently pending jobs in this scheduler
|
404
464
|
# ('at' jobs and 'every' jobs).
|
@@ -411,21 +471,21 @@ module OpenWFE
|
|
411
471
|
# Returns the number of cron jobs currently active in this scheduler.
|
412
472
|
#
|
413
473
|
def cron_job_count
|
414
|
-
@
|
474
|
+
@cron_jobs.size
|
415
475
|
end
|
416
476
|
|
417
477
|
#
|
418
478
|
# Returns the current count of 'every' jobs scheduled.
|
419
479
|
#
|
420
480
|
def every_job_count
|
421
|
-
@pending_jobs.select { |j| j.is_a?(
|
481
|
+
@pending_jobs.select { |j| j.is_a?(EveryJob) }.size
|
422
482
|
end
|
423
483
|
|
424
484
|
#
|
425
485
|
# Returns the current count of 'at' jobs scheduled (not 'every').
|
426
486
|
#
|
427
487
|
def at_job_count
|
428
|
-
@pending_jobs.select { |j| j.instance_of?(
|
488
|
+
@pending_jobs.select { |j| j.instance_of?(AtJob) }.size
|
429
489
|
end
|
430
490
|
|
431
491
|
#
|
@@ -467,15 +527,16 @@ module OpenWFE
|
|
467
527
|
#puts "1 at is '#{at.to_s}' (#{at.class})"}"
|
468
528
|
|
469
529
|
jobClass = if params[:every]
|
470
|
-
|
530
|
+
EveryJob
|
471
531
|
else
|
472
|
-
|
532
|
+
AtJob
|
473
533
|
end
|
474
534
|
|
475
535
|
job_id = params[:job_id]
|
536
|
+
tags = params[:tags]
|
476
537
|
|
477
538
|
b = to_block(params, &block)
|
478
|
-
job = jobClass.new(at, job_id, &b)
|
539
|
+
job = jobClass.new(at, job_id, tags, &b)
|
479
540
|
|
480
541
|
unschedule(job_id) if job_id
|
481
542
|
|
@@ -561,7 +622,7 @@ module OpenWFE
|
|
561
622
|
|
562
623
|
#puts "push() at '#{Time.at(job.at)}'"
|
563
624
|
|
564
|
-
job.
|
625
|
+
job.job_id
|
565
626
|
end
|
566
627
|
|
567
628
|
#
|
@@ -587,20 +648,20 @@ module OpenWFE
|
|
587
648
|
end
|
588
649
|
|
589
650
|
#
|
590
|
-
# cron
|
651
|
+
# cron jobs
|
591
652
|
|
592
653
|
if now.sec == 0 and now.min != @last_cron_minute
|
593
654
|
#
|
594
|
-
# only consider cron
|
655
|
+
# only consider cron jobs at the second 0 of a
|
595
656
|
# minute
|
596
657
|
|
597
658
|
@last_cron_minute = now.min
|
598
659
|
|
599
|
-
#puts "step() @
|
660
|
+
#puts "step() @cron_jobs.size #{@cron_jobs.size}"
|
600
661
|
|
601
|
-
@
|
662
|
+
@cron_jobs.each do |cron_id, cron_job|
|
602
663
|
#puts "step() cron_id : #{cron_id}"
|
603
|
-
trigger(
|
664
|
+
trigger(cron_job) if cron_job.matches?(now)
|
604
665
|
end
|
605
666
|
end
|
606
667
|
|
@@ -635,11 +696,11 @@ module OpenWFE
|
|
635
696
|
end
|
636
697
|
end
|
637
698
|
|
638
|
-
def trigger (
|
699
|
+
def trigger (job)
|
639
700
|
|
640
701
|
Thread.new do
|
641
702
|
begin
|
642
|
-
|
703
|
+
job.trigger
|
643
704
|
rescue Exception => e
|
644
705
|
message =
|
645
706
|
"trigger() caught exception\n" +
|
@@ -672,8 +733,11 @@ module OpenWFE
|
|
672
733
|
protected
|
673
734
|
|
674
735
|
JOB_ID_LOCK = Monitor.new
|
736
|
+
#
|
737
|
+
# would it be better to use a Mutex instead of a full-blown
|
738
|
+
# Monitor ?
|
675
739
|
|
676
|
-
class
|
740
|
+
class Job
|
677
741
|
|
678
742
|
@@last_given_id = 0
|
679
743
|
#
|
@@ -681,51 +745,60 @@ module OpenWFE
|
|
681
745
|
# have persistent ids, a simple counter is sufficient
|
682
746
|
|
683
747
|
attr_accessor \
|
684
|
-
:
|
748
|
+
:job_id, :tags, :block
|
749
|
+
|
750
|
+
def initialize (job_id, tags, &block)
|
685
751
|
|
686
|
-
def initialize (entry_id=nil, &block)
|
687
752
|
@block = block
|
688
|
-
|
689
|
-
|
753
|
+
|
754
|
+
if job_id
|
755
|
+
@job_id = job_id
|
690
756
|
else
|
691
757
|
JOB_ID_LOCK.synchronize do
|
692
|
-
@
|
693
|
-
@@last_given_id = @
|
758
|
+
@job_id = @@last_given_id
|
759
|
+
@@last_given_id = @job_id + 1
|
694
760
|
end
|
695
761
|
end
|
762
|
+
|
763
|
+
#@tags = Array(tags).collect { |tag| tag.to_s }
|
764
|
+
# making sure we have an array of String tags
|
765
|
+
|
766
|
+
@tags = Array(tags)
|
767
|
+
# any tag is OK
|
696
768
|
end
|
697
769
|
|
698
|
-
#
|
699
|
-
#
|
700
|
-
#
|
770
|
+
#
|
771
|
+
# Returns true if this job sports the given tag
|
772
|
+
#
|
773
|
+
def has_tag? (tag)
|
774
|
+
@tags.include?(tag)
|
775
|
+
end
|
701
776
|
end
|
702
777
|
|
703
|
-
class
|
778
|
+
class AtJob < Job
|
704
779
|
|
705
|
-
attr_accessor
|
706
|
-
:at
|
780
|
+
attr_accessor :at
|
707
781
|
|
708
|
-
def initialize (at, at_id, &block)
|
709
|
-
super(at_id, &block)
|
782
|
+
def initialize (at, at_id, tags, &block)
|
783
|
+
super(at_id, tags, &block)
|
710
784
|
@at = at
|
711
785
|
end
|
712
786
|
|
713
787
|
def trigger
|
714
|
-
@block.call @
|
788
|
+
@block.call @job_id, @at
|
715
789
|
end
|
716
790
|
end
|
717
791
|
|
718
|
-
class
|
792
|
+
class EveryJob < AtJob
|
719
793
|
end
|
720
794
|
|
721
|
-
class
|
795
|
+
class CronJob < Job
|
722
796
|
|
723
|
-
attr_accessor
|
724
|
-
:cron_line
|
797
|
+
attr_accessor :cron_line
|
725
798
|
|
726
|
-
def initialize (cron_id, line, &block)
|
799
|
+
def initialize (cron_id, line, tags, &block)
|
727
800
|
|
728
|
-
super(cron_id, &block)
|
801
|
+
super(cron_id, tags, &block)
|
729
802
|
|
730
803
|
if line.kind_of?(String)
|
731
804
|
@cron_line = CronLine.new(line)
|
@@ -733,7 +806,7 @@ module OpenWFE
|
|
733
806
|
@cron_line = line
|
734
807
|
else
|
735
808
|
raise \
|
736
|
-
"Cannot initialize a
|
809
|
+
"Cannot initialize a CronJob " +
|
737
810
|
"with a param of class #{line.class}"
|
738
811
|
end
|
739
812
|
end
|
@@ -743,7 +816,7 @@ module OpenWFE
|
|
743
816
|
end
|
744
817
|
|
745
818
|
def trigger
|
746
|
-
@block.call @
|
819
|
+
@block.call @job_id, @cron_line
|
747
820
|
end
|
748
821
|
end
|
749
822
|
|
@@ -793,7 +866,7 @@ module OpenWFE
|
|
793
866
|
return false if no_match?(time.month, @months)
|
794
867
|
return false if no_match?(time.wday, @weekdays)
|
795
868
|
|
796
|
-
|
869
|
+
true
|
797
870
|
end
|
798
871
|
|
799
872
|
#
|
@@ -835,7 +908,7 @@ module OpenWFE
|
|
835
908
|
item = item.gsub(day, "#{index+1}")
|
836
909
|
end
|
837
910
|
|
838
|
-
|
911
|
+
parse_item(item, 1, 7)
|
839
912
|
end
|
840
913
|
|
841
914
|
def parse_item (item, min, max)
|
@@ -852,7 +925,7 @@ module OpenWFE
|
|
852
925
|
i = min if i < min
|
853
926
|
i = max if i > max
|
854
927
|
|
855
|
-
|
928
|
+
[ i ]
|
856
929
|
end
|
857
930
|
|
858
931
|
def parse_list (item, min, max)
|
@@ -864,7 +937,7 @@ module OpenWFE
|
|
864
937
|
i = max if i > max
|
865
938
|
result << i
|
866
939
|
end
|
867
|
-
|
940
|
+
result
|
868
941
|
end
|
869
942
|
|
870
943
|
def parse_range (item, min, max)
|
@@ -905,7 +978,7 @@ module OpenWFE
|
|
905
978
|
break if value > iend
|
906
979
|
end
|
907
980
|
|
908
|
-
|
981
|
+
result
|
909
982
|
end
|
910
983
|
|
911
984
|
def no_match? (value, cron_values)
|
@@ -916,7 +989,7 @@ module OpenWFE
|
|
916
989
|
return false if value == v
|
917
990
|
end
|
918
991
|
|
919
|
-
|
992
|
+
true
|
920
993
|
end
|
921
994
|
end
|
922
995
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: openwferu-scheduler
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.15.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.9.15.1127
|
7
|
+
date: 2007-10-07 00:00:00 +09:00
|
8
8
|
summary: OpenWFEru scheduler for Ruby (at, cron and every)
|
9
9
|
require_paths:
|
10
10
|
- lib
|