openwferu 0.9.13 → 0.9.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/examples/bigflow.rb +19 -0
  2. data/examples/csv_weather.rb +23 -0
  3. data/examples/engine_template.rb +7 -0
  4. data/lib/openwfe/contextual.rb +0 -2
  5. data/lib/openwfe/engine/engine.rb +137 -34
  6. data/lib/openwfe/engine/file_persisted_engine.rb +0 -5
  7. data/lib/openwfe/exceptions.rb +0 -2
  8. data/lib/openwfe/expool/errorjournal.rb +83 -7
  9. data/lib/openwfe/expool/expressionpool.rb +279 -60
  10. data/lib/openwfe/expool/expstorage.rb +7 -6
  11. data/lib/openwfe/expool/yamlexpstorage.rb +17 -14
  12. data/lib/openwfe/expressions/condition.rb +10 -7
  13. data/lib/openwfe/expressions/environment.rb +11 -1
  14. data/lib/openwfe/expressions/fe_command.rb +14 -1
  15. data/lib/openwfe/expressions/fe_cron.rb +29 -14
  16. data/lib/openwfe/expressions/fe_define.rb +26 -1
  17. data/lib/openwfe/expressions/fe_iterator.rb +2 -0
  18. data/lib/openwfe/expressions/fe_losfor.rb +20 -15
  19. data/lib/openwfe/expressions/fe_misc.rb +0 -2
  20. data/lib/openwfe/expressions/fe_participant.rb +78 -24
  21. data/lib/openwfe/expressions/fe_reserve.rb +0 -2
  22. data/lib/openwfe/expressions/fe_sleep.rb +0 -4
  23. data/lib/openwfe/expressions/fe_subprocess.rb +34 -0
  24. data/lib/openwfe/expressions/fe_value.rb +46 -4
  25. data/lib/openwfe/expressions/fe_wait.rb +0 -2
  26. data/lib/openwfe/expressions/flowexpression.rb +39 -9
  27. data/lib/openwfe/expressions/raw.rb +73 -48
  28. data/lib/openwfe/expressions/raw_prog.rb +45 -15
  29. data/lib/openwfe/expressions/simplerep.rb +54 -7
  30. data/lib/openwfe/expressions/time.rb +5 -2
  31. data/lib/openwfe/expressions/timeout.rb +0 -2
  32. data/lib/openwfe/flowexpressionid.rb +26 -2
  33. data/lib/openwfe/participants/enoparticipants.rb +6 -1
  34. data/lib/openwfe/participants/participant.rb +0 -2
  35. data/lib/openwfe/participants/participantmap.rb +21 -7
  36. data/lib/openwfe/participants/participants.rb +29 -0
  37. data/lib/openwfe/rest/exception.rb +0 -2
  38. data/lib/openwfe/storage/yamlfilestorage.rb +4 -1
  39. data/lib/openwfe/util/dollar.rb +0 -2
  40. data/lib/openwfe/util/lru.rb +0 -2
  41. data/lib/openwfe/util/observable.rb +1 -1
  42. data/lib/openwfe/util/scheduler.rb +4 -4
  43. data/lib/openwfe/util/schedulers.rb +0 -2
  44. data/lib/openwfe/util/workqueue.rb +34 -91
  45. data/lib/openwfe/utils.rb +35 -28
  46. data/lib/openwfe/version.rb +1 -1
  47. data/lib/openwfe/workitem.rb +1 -1
  48. data/test/clone_test.rb +51 -0
  49. data/test/concurrence_test.rb +78 -0
  50. data/test/cron_test_2.rb +50 -0
  51. data/test/flowtestbase.rb +40 -12
  52. data/test/ft_21_cron.rb +32 -6
  53. data/test/ft_26_load.rb +8 -2
  54. data/test/ft_26c_load.rb +19 -0
  55. data/test/ft_27_getflowpos.rb +4 -4
  56. data/test/ft_2_concurrence.rb +14 -9
  57. data/test/ft_32_journal.rb +1 -1
  58. data/test/ft_32c_journal.rb +3 -2
  59. data/test/ft_32d_journal.rb +2 -1
  60. data/test/ft_34_cancelwfid.rb +7 -3
  61. data/test/ft_35_localdefs.rb +13 -0
  62. data/test/ft_38_tag.rb +8 -6
  63. data/test/ft_49_condition.rb +7 -1
  64. data/test/ft_55_ptimeout.rb +13 -14
  65. data/test/ft_57_a.rb +17 -0
  66. data/test/ft_58_ejournal.rb +3 -3
  67. data/test/ft_59_ps.rb +6 -6
  68. data/test/ft_60_ecancel.rb +3 -5
  69. data/test/ft_61_elsub.rb +2 -4
  70. data/test/ft_63_pause.rb +122 -0
  71. data/test/ft_64_alias.rb +102 -0
  72. data/test/ft_64_clone.rb +69 -0
  73. data/test/ft_65_stringlaunch.rb +61 -0
  74. data/test/ft_66_subforget.rb +70 -0
  75. data/test/ft_67_schedlaunch.rb +102 -0
  76. data/test/ft_68_ifparticipant.rb +70 -0
  77. data/test/ft_69_cancelmissing.rb +49 -0
  78. data/test/ft_6_lambda.rb +23 -3
  79. data/test/ft_70_lookupvar.rb +55 -0
  80. data/test/ft_7_lose.rb +1 -1
  81. data/test/ft_tests.rb +10 -1
  82. data/test/hparticipant_test.rb +6 -6
  83. data/test/param_test.rb +1 -1
  84. data/test/{rake_test.rb → rake_ltest.rb} +9 -2
  85. data/test/rake_qtest.rb +3 -1
  86. data/test/raw_prog_test.rb +11 -3
  87. data/test/restart_sleep_test.rb +44 -6
  88. data/test/ruby_procdef_test.rb +129 -0
  89. data/test/rutest_utils.rb +1 -0
  90. data/test/sec_test.rb +3 -3
  91. metadata +19 -4
@@ -51,7 +51,7 @@ module OpenWFE
51
51
  # A very simple directory of participants
52
52
  #
53
53
  class ParticipantMap < Service
54
- include Observable
54
+ include OwfeObservable
55
55
 
56
56
  attr_accessor \
57
57
  :participants
@@ -64,6 +64,14 @@ module OpenWFE
64
64
  @observers = {}
65
65
  end
66
66
 
67
+ #
68
+ # Returns how many participants are currently registered here.
69
+ #
70
+ def size
71
+
72
+ @participants.size
73
+ end
74
+
67
75
  #
68
76
  # Adds a participant to this map.
69
77
  # This method is called by the engine's own register_participant()
@@ -121,7 +129,7 @@ module OpenWFE
121
129
 
122
130
  @participants << [ regex, participant ]
123
131
 
124
- return participant
132
+ participant
125
133
  end
126
134
 
127
135
  #
@@ -137,6 +145,7 @@ module OpenWFE
137
145
  @participants.each do |tuple|
138
146
  return tuple[1] if tuple[0].match(participant_name)
139
147
  end
148
+
140
149
  nil
141
150
  end
142
151
 
@@ -158,17 +167,20 @@ module OpenWFE
158
167
  end
159
168
 
160
169
  #
161
- # Dispatches to the given participant.
170
+ # Dispatches to the given participant (participant name (string) or
162
171
  # The workitem will be fed to the consume() method of that participant.
163
172
  # If it's a cancelitem and the participant has a cancel() method,
164
173
  # it will get called instead.
165
174
  #
166
- def dispatch (participant_name, workitem)
175
+ def dispatch (participant, participant_name, workitem)
176
+
177
+ unless participant
167
178
 
168
- participant = lookup_participant(participant_name)
179
+ participant = lookup_participant participant_name
169
180
 
170
- raise "Didn't find participant named '#{participant_name}'" \
171
- if not participant
181
+ raise "there is no participant named '#{participant_name}'" \
182
+ unless participant
183
+ end
172
184
 
173
185
  workitem.participant_name = participant_name
174
186
 
@@ -184,6 +196,8 @@ module OpenWFE
184
196
 
185
197
  onotify :dispatch, :before_consume, workitem
186
198
 
199
+ workitem.dispatch_time = Time.now
200
+
187
201
  participant.consume(workitem)
188
202
 
189
203
  onotify :dispatch, :after_consume, workitem
@@ -177,6 +177,35 @@ module OpenWFE
177
177
  end
178
178
  end
179
179
 
180
+ #
181
+ # Simply aliasing a participant.
182
+ #
183
+ # engine.register_participant "toto" do |workitem|
184
+ # workitem.toto_message = "toto was here"
185
+ # end
186
+ # engine.register_participant "user_.*", AliasParticipant.new("toto")
187
+ #
188
+ # Workitems for participant whose name starts with 'user_' will be handled
189
+ # by participant 'toto'.
190
+ # Note that you can't use use a regex as the aliased name ("toto" in the
191
+ # example).
192
+ #
193
+ class AliasParticipant
194
+ include LocalParticipant
195
+
196
+ attr_reader :aliased_name
197
+
198
+ def initialize (aliased_name)
199
+
200
+ @aliased_name = aliased_name
201
+ end
202
+
203
+ def consume (workitem)
204
+
205
+ get_participant_map.dispatch(nil, @aliased_name, workitem)
206
+ end
207
+ end
208
+
180
209
  #
181
210
  # The NullParticipant never replies, it simply discards the workitems
182
211
  # it receives.
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id: exception.rb 3454 2006-10-08 16:51:00Z jmettraux $
34
- #
35
33
 
36
34
  #
37
35
  # "hecho en Costa Rica"
@@ -140,8 +140,10 @@ module OpenWFE
140
140
  fei_path = compute_file_path(fei)
141
141
 
142
142
  if not File.exist?(fei_path)
143
+
143
144
  ldebug { "[] didn't find file at #{fei_path}" }
144
145
  #puts "[] didn't find file at #{fei_path}"
146
+
145
147
  return nil
146
148
  end
147
149
 
@@ -184,7 +186,8 @@ module OpenWFE
184
186
 
185
187
  count += 1 if OpenWFE::ends_with(path, ".yaml")
186
188
  end
187
- return count
189
+
190
+ count
188
191
  end
189
192
 
190
193
  #
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
- #
35
33
 
36
34
  #
37
35
  # "made in Japan"
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id$
34
- #
35
33
 
36
34
  #
37
35
  # "made in Japan"
@@ -45,7 +45,7 @@ module OpenWFE
45
45
  # available.
46
46
  # This mixin is chiefly used by the ExpressionPool class.
47
47
  #
48
- module Observable
48
+ module OwfeObservable
49
49
 
50
50
  #
51
51
  # Observers will register themselves to the Observable via
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
- #
35
33
 
36
34
  #
37
35
  # "made in Japan"
@@ -601,6 +599,8 @@ module OpenWFE
601
599
 
602
600
  @last_cron_minute = minute
603
601
 
602
+ #puts "step() @cron_entries.size #{@cron_entries.size}"
603
+
604
604
  @cron_entries.each do |cron_id, cron_entry|
605
605
  #puts "step() cron_id : #{cron_id}"
606
606
  trigger(cron_entry) if cron_entry.matches? now
@@ -729,9 +729,9 @@ module OpenWFE
729
729
 
730
730
  super(cron_id, &block)
731
731
 
732
- if line.kind_of? String
732
+ if line.kind_of?(String)
733
733
  @cron_line = CronLine.new(line)
734
- elsif line.kind_of? CronLine
734
+ elsif line.kind_of?(CronLine)
735
735
  @cron_line = line
736
736
  else
737
737
  raise \
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
- #
35
33
 
36
34
  #
37
35
  # "made in Japan"
@@ -43,133 +43,76 @@ require 'openwfe/utils'
43
43
 
44
44
  module OpenWFE
45
45
 
46
+ #
47
+ # This mixin provides a workqueue and a thread for executing tasks
48
+ # pushed onto it. It uses the thread.rb Queue class.
49
+ #
50
+ # It is currently only used by the ExpressionPool (maybe it'll get
51
+ # merged back into it later).
52
+ #
46
53
  module WorkqueueMixin
47
54
 
48
- WQF_LOW = 0.500
49
-
50
55
  #
51
- # Starts the workqueue with a given frequency (seconds)
56
+ # Creates and starts the workqueue.
52
57
  #
53
58
  def start_workqueue
54
59
 
55
- @workqueue_mutex = Mutex.new
56
- @workqueue = []
57
- @workqueue_frequency = 0
60
+ @workqueue = Queue.new
61
+
62
+ @workstopped = false
58
63
 
59
64
  OpenWFE::call_in_thread "workqueue", self do
60
- while true
61
- break if @workqueue_frequency == nil
62
- sleep @workqueue_frequency
63
- do_process_workqueue
65
+ loop do
66
+ do_process_workelement @workqueue.pop
67
+ break if @workstopped and @workqueue.empty?
64
68
  end
65
69
  end
66
70
  end
67
71
 
68
72
  #
69
- # Returns true if there is or there just was activity for the ]
73
+ # Returns true if there is or there just was activity for the
70
74
  # work queue.
71
75
  #
72
76
  def is_workqueue_busy?
73
- (@workqueue.size > 0 or @workqueue_frequency < WQF_LOW)
77
+
78
+ @workqueue.size > 0
74
79
  end
75
80
 
76
81
  #
77
82
  # Stops the workqueue.
78
83
  #
79
84
  def stop_workqueue
80
- @workqueue_frequency = nil
81
- do_process_workqueue
82
- #
83
- # maybe could process the work queue until it's really empty
85
+
86
+ @workstopped = true
84
87
  end
85
88
 
86
89
  #
87
90
  # the method called by the mixer to actually queue the work.
88
91
  #
89
92
  def queue_work (*args)
90
- @workqueue_mutex.synchronize do
91
-
92
- if @workqueue
93
- @workqueue.push args
94
- #
95
- # work will be done later (millisec order)
96
- # by the work thread
97
- else
98
- do_process_workelement args
99
- #
100
- # degraded mode : as if there were no workqueue
101
- end
102
- end
103
- end
104
-
105
- #
106
- # Returns the current workqueue size
107
- #
108
- def workqueue_size
109
- return 0 unless @workqueue
110
- @workqueue.size
111
- end
112
-
113
- #
114
- # Called by the workqueue thread, copies the workqueue and clears
115
- # it, and then processes the elt in the copied workqueue.
116
- # (meanwhile, the empty workqueue gets filled by queue_work()
117
- # calls)
118
- #
119
- # This method calls the do_process_workelement() method of
120
- # its 'mixer' with each work element queued.
121
- #
122
- def do_process_workqueue
123
-
124
- q = nil
125
93
 
126
- @workqueue_mutex.synchronize do
94
+ if @workqueue_stopped
127
95
 
128
- if @workqueue.size < 1
129
- increment_workqueue_frequency
130
- return
131
- end
132
-
133
- q = Array.new(@workqueue)
134
- @workqueue.clear
135
-
136
- @workqueue_frequency = 0
96
+ do_process_workelement args
137
97
  #
138
- # back to maximum reponsiveness
139
- end
98
+ # degraded mode : as if there were no workqueue
99
+ else
140
100
 
141
- #ldebug { "do_process_workqueue() #{q.size} items to process" }
142
-
143
- q.each do |elt|
144
-
145
- do_process_workelement elt
101
+ @workqueue.push args
146
102
  #
147
- # exception management is now done in the
148
- # do_process_workelement method
103
+ # work will be done later (millisec order)
104
+ # by the work thread
149
105
  end
150
-
151
- # TODO : have a pool of workers handle that
152
-
153
- #q.size
154
106
  end
155
107
 
156
- protected
157
-
158
- #
159
- # No activity spotted, so decrease responsiveness
160
- #
161
- def increment_workqueue_frequency
162
-
163
- return if @workqueue_frequency == nil
164
-
165
- @workqueue_frequency *= 3
166
-
167
- if @workqueue_frequency == 0
168
- @workqueue_frequency = 0.001
169
- elsif @workqueue_frequency > WQF_LOW
170
- @workqueue_frequency = WQF_LOW
171
- end
172
- end
108
+ #--
109
+ # Returns the current workqueue size
110
+ #
111
+ #def workqueue_size
112
+ # return 0 unless @workqueue
113
+ # @workqueue.size
114
+ #end
115
+ #++
173
116
  end
174
117
  end
175
118
 
data/lib/openwfe/utils.rb CHANGED
@@ -65,37 +65,20 @@ module OpenWFE
65
65
  exit 1
66
66
  end
67
67
 
68
- #
69
- # Attempts a deep cloning of the object
70
- #
71
- def OpenWFE.copy (object)
72
-
73
- return nil if object == nil
74
-
75
- if object.kind_of?(Array)
76
- result = []
77
- object.each do |i|
78
- result << copy(i)
79
- end
80
- return result
81
- end
82
-
83
- if object.kind_of?(Hash)
84
- result = {}
85
- object.each do |k, v|
86
- result[copy(k)] = copy(v)
87
- end
88
- return result
89
- end
90
-
91
- return object.dup
92
- end
93
-
94
68
  #
95
69
  # see
96
70
  # http://wiki.rubygarden.org/Ruby/page/show/Make_A_Deep_Copy_Of_An_Object
97
71
  #
72
+ # It's not perfect (that's why fulldup() uses it only in certain cases).
73
+ #
74
+ # For example :
75
+ #
76
+ # TypeError: singleton can't be dumped
77
+ # ./lib/openwfe/utils.rb:74:in `dump'
78
+ # ./lib/openwfe/utils.rb:74:in `deep_clone'
79
+ #
98
80
  def OpenWFE.deep_clone (object)
81
+
99
82
  Marshal::load(Marshal.dump(object))
100
83
  end
101
84
 
@@ -125,7 +108,13 @@ module OpenWFE
125
108
  return d.root
126
109
  end
127
110
 
128
- o = object.class.new
111
+ o = nil
112
+
113
+ begin
114
+ o = object.class.new
115
+ rescue ArgumentError
116
+ return deep_clone(object)
117
+ end
129
118
 
130
119
  #
131
120
  # some kind of collection ?
@@ -136,7 +125,7 @@ module OpenWFE
136
125
  end
137
126
  elsif object.kind_of?(Hash)
138
127
  object.each do |k, v|
139
- o[copy(k)] = fulldup(v)
128
+ o[fulldup(k)] = fulldup(v)
140
129
  end
141
130
  end
142
131
 
@@ -194,6 +183,8 @@ module OpenWFE
194
183
  #
195
184
  def OpenWFE.parse_uri (string)
196
185
 
186
+ return nil if string.split("\n").size > 1
187
+
197
188
  begin
198
189
  return URI::parse(string)
199
190
  rescue Exception => e
@@ -459,6 +450,22 @@ module OpenWFE
459
450
  container[key[i+1..-1]] = value
460
451
  end
461
452
 
453
+ #
454
+ # Returns true if this host is currently online (has access to the web /
455
+ # internet).
456
+ #
457
+ def online?
458
+
459
+ require 'open-uri'
460
+
461
+ begin
462
+ open("http://www.openwfe.org")
463
+ true
464
+ rescue SocketError => se
465
+ false
466
+ end
467
+ end
468
+
462
469
  protected
463
470
 
464
471
  def pop_key (key)
@@ -32,5 +32,5 @@
32
32
  #
33
33
 
34
34
  module OpenWFE
35
- OPENWFERU_VERSION = '0.9.13'
35
+ OPENWFERU_VERSION = '0.9.14'
36
36
  end
@@ -202,7 +202,7 @@ module OpenWFE
202
202
  attr_accessor :flow_expression_id, :participant_name
203
203
 
204
204
  def last_expression_id
205
- return @flow_expression_id
205
+ @flow_expression_id
206
206
  end
207
207
 
208
208
  def last_expression_id= (fei)
@@ -0,0 +1,51 @@
1
+
2
+ #
3
+ # Testing OpenWFEru
4
+ #
5
+ # John Mettraux at openwfe.org
6
+ #
7
+
8
+ require 'test/unit'
9
+
10
+ require 'openwfe/utils'
11
+
12
+
13
+ class FullDupTest < Test::Unit::TestCase
14
+
15
+ #def setup
16
+ #end
17
+
18
+ #def teardown
19
+ #end
20
+
21
+ class MyClass
22
+
23
+ attr_reader :name
24
+
25
+ def initialize (name)
26
+ @name = name
27
+ end
28
+ end
29
+
30
+ def test_fulldup
31
+
32
+ o0 = MyClass.new("cow")
33
+
34
+ o1 = OpenWFE.fulldup(o0)
35
+
36
+ assert_not_equal o0.object_id, o1.object_id
37
+ assert_equal o0.name, o1.name
38
+ end
39
+
40
+ def test_yaml
41
+
42
+ require 'yaml'
43
+
44
+ o0 = MyClass.new("pig")
45
+ o1 = YAML.load(o0.to_yaml)
46
+
47
+ assert_not_equal o0.object_id, o1.object_id
48
+ assert_equal o0.name, o1.name
49
+ end
50
+
51
+ end
@@ -0,0 +1,78 @@
1
+ #
2
+ # Testing OpenWFE
3
+ #
4
+ # John Mettraux at openwfe.org
5
+ #
6
+ # Sun Oct 29 15:41:44 JST 2006
7
+ #
8
+ # Kita Yokohama
9
+ #
10
+
11
+ require 'test/unit'
12
+
13
+ #require 'openwfe/workitem'
14
+ #require 'openwfe/flowexpressionid'
15
+ require 'openwfe/engine/engine'
16
+ require 'openwfe/expressions/raw_prog'
17
+ require 'openwfe/worklist/storeparticipant'
18
+
19
+ include OpenWFE
20
+
21
+
22
+ class ConcurrenceAndParticipantTest < Test::Unit::TestCase
23
+
24
+ def setup
25
+ @engine = Engine.new()
26
+ end
27
+
28
+ #def teardown
29
+ #end
30
+
31
+ #
32
+ # concurrence test
33
+
34
+ class Hpc0 < ProcessDefinition
35
+ concurrence do
36
+ #participant :alice
37
+ #participant :bob
38
+ alice
39
+ bob
40
+ end
41
+ end
42
+
43
+ def test_hpc_0
44
+
45
+ @hpAlice = HashParticipant.new
46
+ @hpBob = HashParticipant.new
47
+
48
+ @engine.register_participant(:alice, @hpAlice)
49
+ @engine.register_participant(:bob, @hpBob)
50
+
51
+ @engine.launch(Hpc0)
52
+
53
+ sleep 0.100
54
+
55
+ assert_equal @hpAlice.size, 1
56
+ assert_equal @hpBob.size, 1
57
+ end
58
+
59
+ def test_1
60
+
61
+ @engine.register_participant :alice do |workitem|
62
+ puts "alice in"
63
+ sleep 0.100
64
+ puts "alice out"
65
+ end
66
+ @engine.register_participant :bob do |workitem|
67
+ puts "bob in"
68
+ sleep 0.100
69
+ puts "bob out"
70
+ end
71
+
72
+ @engine.launch Hpc0
73
+
74
+ sleep 2
75
+ end
76
+
77
+ end
78
+
@@ -0,0 +1,50 @@
1
+
2
+ #
3
+ # Testing OpenWFE
4
+ #
5
+ # John Mettraux at openwfe.org
6
+ #
7
+ # Sun Oct 29 16:18:25 JST 2006
8
+ #
9
+
10
+ require 'test/unit'
11
+
12
+ require 'openwfe/util/otime'
13
+ require 'openwfe/util/scheduler'
14
+
15
+
16
+ #
17
+ # testing otime and the scheduler (its cron aspect)
18
+ #
19
+ class CronTest2 < Test::Unit::TestCase
20
+
21
+ #def setup
22
+ #end
23
+
24
+ #def teardown
25
+ #end
26
+
27
+ def t_0
28
+
29
+ $var = 0
30
+
31
+ scheduler = OpenWFE::Scheduler.new
32
+ scheduler.start
33
+
34
+ scheduler.schedule '* * * * *' do
35
+ $var += 1
36
+ end
37
+
38
+ sleep 1
39
+ scheduler.stop
40
+
41
+ puts Time.now
42
+ puts "XXX #{$var}" if $var != 0
43
+ end
44
+
45
+ def test_0
46
+ 300.times do
47
+ t_0
48
+ end
49
+ end
50
+ end