time_scheduler 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +70 -1
- data/README.ja.adoc +70 -1
- data/Rakefile +9 -9
- data/lib/time_scheduler/scheduler.rb +48 -0
- data/lib/time_scheduler/version.rb +1 -1
- data/sample/base_h.rb +17 -0
- data/time_scheduler.gemspec +1 -2
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e58dc40f89e8573c41d5817583a7146d359d70077761dbbe92fadd6eb8096b3
|
4
|
+
data.tar.gz: 73d28d42cea43c9b96fae6c65b3d032ad2f4c29c5e00396b245e40cf4f872229
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 469f48427b2a4dc21d4ce6a52f6d744274befe725cad72f79e5996c459419b0c9c4f30d3dcabc5926e012e41f95df4197978c4b7d77b0767b21fee7428edbeef
|
7
|
+
data.tar.gz: 560d58d6fc0ad2e8f54e50df8ceacd0839f37c85a86dab3de68cb3d99660cc74d13d2d8f70494012cb51f12bed5c4dda994d30fb86ea1bf517ece3280cc48638
|
data/README.adoc
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
Yet another library for single/periodical event scheduler.
|
4
4
|
|
5
|
+
== Features
|
6
|
+
|
7
|
+
* A thread based scheduler that runs once or periodically at a specified datetime.
|
8
|
+
* The condition is specified by a format such as crontab or by keyword argument.
|
9
|
+
* Time can be specified in less than 1 second. However, the behavior depends on the environment.
|
10
|
+
* Suspend/resume function.
|
11
|
+
* Function to change the datetime conditions during execution.
|
12
|
+
* Runs only once within the specified timelimit.
|
13
|
+
|
5
14
|
== Installation
|
6
15
|
|
7
16
|
Add this line to your application's Gemfile:
|
@@ -78,6 +87,28 @@ end
|
|
78
87
|
sleep
|
79
88
|
----
|
80
89
|
|
90
|
+
=== Example 3
|
91
|
+
|
92
|
+
[source,ruby]
|
93
|
+
----
|
94
|
+
require "time_scheduler"
|
95
|
+
|
96
|
+
Scheduler = TimeScheduler.new
|
97
|
+
|
98
|
+
(0..4).each do
|
99
|
+
p [Time.now.iso8601(3), :cycle]
|
100
|
+
Scheduler.first_only( timeout: 10 ) do
|
101
|
+
p [Time.now.iso8601(3), :first]
|
102
|
+
end
|
103
|
+
Scheduler.last_only( timeout: 10 ) do
|
104
|
+
p [Time.now.iso8601(3), :last]
|
105
|
+
end
|
106
|
+
sleep 1
|
107
|
+
end
|
108
|
+
|
109
|
+
sleep
|
110
|
+
----
|
111
|
+
|
81
112
|
== Reference
|
82
113
|
|
83
114
|
=== Create a new TimeScheduler.
|
@@ -98,7 +129,8 @@ TimeScheduler.new
|
|
98
129
|
[source,ruby]
|
99
130
|
----
|
100
131
|
TimeScheduler#wait( topic = Time.now.iso8601(6),
|
101
|
-
at: nil, cron: nil, year: nil, month: nil, day: nil, wday: nil,
|
132
|
+
at: nil, cron: nil, year: nil, month: nil, day: nil, wday: nil,
|
133
|
+
hour: nil, min: nil, sec: 0, msec: nil,
|
102
134
|
&block )
|
103
135
|
----
|
104
136
|
|
@@ -121,6 +153,7 @@ TimeScheduler#wait( topic = Time.now.iso8601(6),
|
|
121
153
|
** sec: second. 0..59. (default: 0)
|
122
154
|
** msec: millisecond. 0..999. (default: nil), If msec is assigned, then other parameters are ignored.
|
123
155
|
In detail, it can use "*" as wildcard.
|
156
|
+
** block: Contents to be executed at a datetime that match the condition.
|
124
157
|
|
125
158
|
* Block Parameter:
|
126
159
|
** time: event time. time object.
|
@@ -190,6 +223,40 @@ TimeScheduler#resume
|
|
190
223
|
* Parameter:
|
191
224
|
** none.
|
192
225
|
|
226
|
+
=== Invoke the block only once at the beginning, and ignoring recalls within the time limit.
|
227
|
+
|
228
|
+
[source,ruby]
|
229
|
+
----
|
230
|
+
TimeScheduler#first_only( ident = nil, timeout: 1, &block )
|
231
|
+
----
|
232
|
+
|
233
|
+
* Result:
|
234
|
+
** nil.
|
235
|
+
|
236
|
+
* Parameter:
|
237
|
+
** ident: Additional Identifier.
|
238
|
+
** timeout: Monitoring time limit (sec).
|
239
|
+
|
240
|
+
* Block Parameter:
|
241
|
+
** none.
|
242
|
+
|
243
|
+
=== When there is no recall within the time limit, invoke the block only once at the end.
|
244
|
+
|
245
|
+
[source,ruby]
|
246
|
+
----
|
247
|
+
TimeScheduler#last_only( ident = nil, timeout: 1, &block )
|
248
|
+
----
|
249
|
+
|
250
|
+
* Result:
|
251
|
+
** nil.
|
252
|
+
|
253
|
+
* Parameter:
|
254
|
+
** ident: Additional Identifier.
|
255
|
+
** timeout: Monitoring time limit (sec).
|
256
|
+
|
257
|
+
* Block Parameter:
|
258
|
+
** none.
|
259
|
+
|
193
260
|
== Caution
|
194
261
|
|
195
262
|
Because it is calculated in local time, it does not work as expected when switching to daylight saving time.
|
@@ -201,3 +268,5 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/arimay
|
|
201
268
|
== License
|
202
269
|
|
203
270
|
The gem is available as open source under the terms of the http://opensource.org/licenses/MIT[MIT License].
|
271
|
+
|
272
|
+
Copyright (c) ARIMA Yasuhiro <arima.yasuhiro@gmail.com>
|
data/README.ja.adoc
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
一度の/周期的なイベントスケジューラのライブラリのひとつ。
|
4
4
|
|
5
|
+
== 特徴
|
6
|
+
|
7
|
+
* 条件指定された日時に一度だけまたは周期的に動作するスレッドベースのスケジューラ.
|
8
|
+
* 条件は crontab のような書式や、キーワード引数で指定する.
|
9
|
+
* 時刻は1秒未満で指定することが可能. ただし、挙動は環境依存.
|
10
|
+
* 一時停止/再開機能.
|
11
|
+
* 実行中の日時条件変更機能.
|
12
|
+
* 指定された制限時間内に一度だけ実行する.
|
13
|
+
|
5
14
|
== 導入
|
6
15
|
|
7
16
|
アプリの Gemfile にこの行を追加
|
@@ -78,6 +87,28 @@ end
|
|
78
87
|
sleep
|
79
88
|
----
|
80
89
|
|
90
|
+
=== Example 3
|
91
|
+
|
92
|
+
[source,ruby]
|
93
|
+
----
|
94
|
+
require "time_scheduler"
|
95
|
+
|
96
|
+
Scheduler = TimeScheduler.new
|
97
|
+
|
98
|
+
(0..4).each do
|
99
|
+
p [Time.now.iso8601(3), :cycle]
|
100
|
+
Scheduler.first_only( timeout: 10 ) do
|
101
|
+
p [Time.now.iso8601(3), :first]
|
102
|
+
end
|
103
|
+
Scheduler.last_only( timeout: 10 ) do
|
104
|
+
p [Time.now.iso8601(3), :last]
|
105
|
+
end
|
106
|
+
sleep 1
|
107
|
+
end
|
108
|
+
|
109
|
+
sleep
|
110
|
+
----
|
111
|
+
|
81
112
|
== リファレンス
|
82
113
|
|
83
114
|
=== 新たな TimeScheduler を作成する.
|
@@ -98,7 +129,8 @@ TimeScheduler.new
|
|
98
129
|
[source,ruby]
|
99
130
|
----
|
100
131
|
TimeScheduler#wait( topic = Time.now.iso8601(6),
|
101
|
-
at: nil, cron: nil, year: nil, month: nil, day: nil, wday: nil,
|
132
|
+
at: nil, cron: nil, year: nil, month: nil, day: nil, wday: nil,
|
133
|
+
hour: nil, min: nil, sec: 0, msec: nil,
|
102
134
|
&block )
|
103
135
|
----
|
104
136
|
|
@@ -121,6 +153,7 @@ TimeScheduler#wait( topic = Time.now.iso8601(6),
|
|
121
153
|
** sec: 秒. 0..59. (default: 0)
|
122
154
|
** msec: ミリ秒. 0..999. (default: nil), ミリ秒が指定されたとき, 他のパラメータは無視される.
|
123
155
|
詳細では, ワイルドカードとして "*" を使用できる.
|
156
|
+
** block: 条件に適合する日時に実行する内容.
|
124
157
|
|
125
158
|
* Block Parameter:
|
126
159
|
** time: イベント日時. Time オブジェクト.
|
@@ -190,6 +223,40 @@ TimeScheduler#resume
|
|
190
223
|
* Parameter:
|
191
224
|
** なし.
|
192
225
|
|
226
|
+
=== 最初に一度だけブロックを呼び出して、制限時間内の再呼び出しは無視する.
|
227
|
+
|
228
|
+
[source,ruby]
|
229
|
+
----
|
230
|
+
TimeScheduler#first_only( ident = nil, timeout: 1, &block )
|
231
|
+
----
|
232
|
+
|
233
|
+
* Result:
|
234
|
+
** nil.
|
235
|
+
|
236
|
+
* Parameter:
|
237
|
+
** ident: 追加識別子.
|
238
|
+
** timeout: 監視時間制限(秒).
|
239
|
+
|
240
|
+
* Block Parameter:
|
241
|
+
** なし.
|
242
|
+
|
243
|
+
=== 制限時間内に再呼び出しがないとき、最後に一度だけブロックを呼び出す.
|
244
|
+
|
245
|
+
[source,ruby]
|
246
|
+
----
|
247
|
+
TimeScheduler#last_only( ident = nil, timeout: 1, &block )
|
248
|
+
----
|
249
|
+
|
250
|
+
* Result:
|
251
|
+
** nil.
|
252
|
+
|
253
|
+
* Parameter:
|
254
|
+
** ident: 追加識別子.
|
255
|
+
** timeout: 監視時間制限(秒).
|
256
|
+
|
257
|
+
* Block Parameter:
|
258
|
+
** なし.
|
259
|
+
|
193
260
|
== 注意
|
194
261
|
|
195
262
|
地域時刻で計算しているため、夏時間の切り替わりにおいて期待しない挙動となる.
|
@@ -201,3 +268,5 @@ TimeScheduler#resume
|
|
201
268
|
== ライセンス
|
202
269
|
|
203
270
|
この Gem は、 http://opensource.org/licenses/MIT[MITライセンス] の条件に基づいてオープンソースとして入手できる.
|
271
|
+
|
272
|
+
Copyright (c) ARIMA Yasuhiro <arima.yasuhiro@gmail.com>
|
data/Rakefile
CHANGED
@@ -8,12 +8,12 @@ task :default => :spec
|
|
8
8
|
|
9
9
|
class Bundler::GemHelper
|
10
10
|
|
11
|
-
def git_archive( dir = "
|
11
|
+
def git_archive( dir = "../zip" )
|
12
12
|
FileUtils.mkdir_p dir
|
13
13
|
dest_path = File.join(dir, "#{name}-#{version}.zip")
|
14
14
|
cmnd = "git archive --format zip --prefix=#{name}/ HEAD > #{dest_path}"
|
15
15
|
|
16
|
-
|
16
|
+
_, code = sh_with_status( cmnd )
|
17
17
|
raise "Couldn't archive gem," unless code == 0
|
18
18
|
|
19
19
|
Bundler.ui.confirm "#{name} #{version} archived to #{dest_path}."
|
@@ -23,11 +23,11 @@ class Bundler::GemHelper
|
|
23
23
|
ver = version.to_s
|
24
24
|
|
25
25
|
cmnd = "git push origin #{ver} "
|
26
|
-
|
26
|
+
_, code = sh_with_status( cmnd )
|
27
27
|
raise "Couldn't git push origin." unless code == 0
|
28
28
|
|
29
29
|
cmnd = "git push "
|
30
|
-
|
30
|
+
_, code = sh_with_status( cmnd )
|
31
31
|
raise "Couldn't git push." unless code == 0
|
32
32
|
|
33
33
|
Bundler.ui.confirm "Git Push #{ver}."
|
@@ -43,15 +43,15 @@ class Bundler::GemHelper
|
|
43
43
|
end
|
44
44
|
|
45
45
|
cmnd = "git add #{version_pathname} "
|
46
|
-
|
46
|
+
_, code = sh_with_status( cmnd )
|
47
47
|
raise "Couldn't git add," unless code == 0
|
48
48
|
|
49
49
|
cmnd = "git commit -m '#{new_version}' "
|
50
|
-
|
50
|
+
_, code = sh_with_status( cmnd )
|
51
51
|
raise "Couldn't git commit." unless code == 0
|
52
52
|
|
53
53
|
cmnd = "git tag #{new_version} "
|
54
|
-
|
54
|
+
_, code = sh_with_status( cmnd )
|
55
55
|
raise "Couldn't git tag." unless code == 0
|
56
56
|
|
57
57
|
Bundler.ui.confirm "Update Tags to #{new_version}."
|
@@ -80,14 +80,14 @@ Bundler::GemHelper.new(Dir.pwd).instance_eval do
|
|
80
80
|
|
81
81
|
desc "Update Version Minor"
|
82
82
|
task 'minor' do
|
83
|
-
major, minor,
|
83
|
+
major, minor, _tiny = version.to_s.split('.')
|
84
84
|
new_version = [major, minor.to_i + 1, 0].join('.')
|
85
85
|
update_version( new_version )
|
86
86
|
end
|
87
87
|
|
88
88
|
desc "Update Version Major"
|
89
89
|
task 'major' do
|
90
|
-
major,
|
90
|
+
major, _minor, _tiny = version.to_s.split('.')
|
91
91
|
new_version = [major.to_i + 1, 0, 0].join('.')
|
92
92
|
update_version( new_version )
|
93
93
|
end
|
@@ -179,7 +179,35 @@ class TimeScheduler
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
+
class Counter
|
183
|
+
def initialize
|
184
|
+
@count = 0
|
185
|
+
@mutex = Mutex.new
|
186
|
+
end
|
187
|
+
|
188
|
+
def incr
|
189
|
+
@mutex.synchronize do
|
190
|
+
@count += 1
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def decr
|
195
|
+
@mutex.synchronize do
|
196
|
+
@count -= 1 if @count > 0
|
197
|
+
@count
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def reset
|
202
|
+
@mutex.synchronize do
|
203
|
+
@count = 0
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
182
208
|
def initialize
|
209
|
+
@first_counter = Hash.new{|h,k| h[k] = Counter.new }
|
210
|
+
@last_counter = Hash.new{|h,k| h[k] = Counter.new }
|
183
211
|
end
|
184
212
|
|
185
213
|
def scheduler
|
@@ -222,5 +250,25 @@ class TimeScheduler
|
|
222
250
|
TimeScheduler::Schedule.resume
|
223
251
|
end
|
224
252
|
|
253
|
+
def first_only( ident = nil, timeout: 1, &block )
|
254
|
+
key = [ caller[0], ident.to_s ].join(":")
|
255
|
+
count = @first_counter[key].incr
|
256
|
+
block.call if count == 1
|
257
|
+
::Thread.start( key ) do |key|
|
258
|
+
::Kernel.sleep timeout
|
259
|
+
@first_counter[key].decr
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def last_only( ident = nil, timeout: 1, &block )
|
264
|
+
key = [ caller[0], ident.to_s ].join(":")
|
265
|
+
@last_counter[key].incr
|
266
|
+
::Thread.start( key ) do |key|
|
267
|
+
::Kernel.sleep timeout
|
268
|
+
count = @last_counter[key].decr
|
269
|
+
block.call if count == 0
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
225
273
|
end
|
226
274
|
|
data/sample/base_h.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "time_scheduler"
|
2
|
+
|
3
|
+
Scheduler = TimeScheduler.new
|
4
|
+
|
5
|
+
(0..4).each do
|
6
|
+
p [Time.now.iso8601(3), :cycle]
|
7
|
+
Scheduler.first_only( timeout: 10 ) do
|
8
|
+
p [Time.now.iso8601(3), :first]
|
9
|
+
end
|
10
|
+
Scheduler.last_only( timeout: 10 ) do
|
11
|
+
p [Time.now.iso8601(3), :last]
|
12
|
+
end
|
13
|
+
sleep 1
|
14
|
+
end
|
15
|
+
|
16
|
+
Scheduler.wait( at: Time.now + 10 )
|
17
|
+
p [Time.now.iso8601(3), :quit]
|
data/time_scheduler.gemspec
CHANGED
@@ -11,9 +11,8 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.summary = %q{ Library for simple event scheduler. }
|
12
12
|
spec.description = %q{ Yet another library for single/periodical event scheduler. }
|
13
13
|
spec.homepage = "https://github.com/arimay/time_scheduler"
|
14
|
+
spec.license = "MIT"
|
14
15
|
|
15
|
-
# Specify which files should be added to the gem when it is released.
|
16
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
17
16
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
18
17
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: time_scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- arimay
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: time_cursor
|
@@ -88,9 +88,11 @@ files:
|
|
88
88
|
- sample/base_e.rb
|
89
89
|
- sample/base_f.rb
|
90
90
|
- sample/base_g.rb
|
91
|
+
- sample/base_h.rb
|
91
92
|
- time_scheduler.gemspec
|
92
93
|
homepage: https://github.com/arimay/time_scheduler
|
93
|
-
licenses:
|
94
|
+
licenses:
|
95
|
+
- MIT
|
94
96
|
metadata: {}
|
95
97
|
post_install_message:
|
96
98
|
rdoc_options: []
|