delayer 1.0.2 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +5 -5
- data/Steepfile +19 -0
- data/delayer.gemspec +1 -1
- data/lib/delayer.rb +5 -4
- data/lib/delayer/delayed_procedure.rb +56 -0
- data/lib/delayer/error.rb +2 -0
- data/lib/delayer/extend.rb +85 -23
- data/lib/delayer/procedure.rb +1 -1
- data/lib/delayer/version.rb +1 -1
- data/sig/delayer.rbs +150 -0
- data/test/test_delayer.rb +108 -0
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 003a08fd66333486ef3f6512418dbffb7141a8e8f2d172b0c6ab0f3ce60f439c
|
4
|
+
data.tar.gz: b5dc15813a92615447be5651e301e5741196b63e545bdb56d1b68b718e46eec7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 184ca832fc9514afb30279377c9eae948e659ebb0f8035f307231cc4482450f65c57abf81e8eeecd03a03ab6d753894e5c1fc742a26519ee771aacde0ad7c76d
|
7
|
+
data.tar.gz: 0f2445e26823d95c2d98871ff18ec3016d7f78f2828df90bdbfd8877f1ccb3001d27fff0dee60d98b0eb7c8d270c36b3277de23d3498a4393fbb478ca0b0806b
|
data/.circleci/config.yml
CHANGED
@@ -29,12 +29,12 @@ jobs:
|
|
29
29
|
workflows:
|
30
30
|
build:
|
31
31
|
jobs:
|
32
|
-
- build:
|
33
|
-
name: 'ruby-2.5'
|
34
|
-
ruby-version: '2.5.7'
|
35
32
|
- build:
|
36
33
|
name: 'ruby-2.6'
|
37
|
-
ruby-version: '2.6.
|
34
|
+
ruby-version: '2.6.7'
|
38
35
|
- build:
|
39
36
|
name: 'ruby-2.7'
|
40
|
-
ruby-version: '2.7.
|
37
|
+
ruby-version: '2.7.3'
|
38
|
+
- build:
|
39
|
+
name: 'ruby-3.0'
|
40
|
+
ruby-version: '3.0.1'
|
data/Steepfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
target :lib do
|
2
|
+
signature "sig"
|
3
|
+
check "lib" # Directory name
|
4
|
+
# ignore "lib/templates/*.rb"
|
5
|
+
# library "pathname", "set" # Standard libraries
|
6
|
+
# library "strong_json" # Gems
|
7
|
+
# library "instance_storage"
|
8
|
+
library "monitor"
|
9
|
+
library "set"
|
10
|
+
end
|
11
|
+
|
12
|
+
# target :spec do
|
13
|
+
# signature "sig", "sig-private"
|
14
|
+
#
|
15
|
+
# check "spec"
|
16
|
+
#
|
17
|
+
# # library "pathname", "set" # Standard libraries
|
18
|
+
# # library "rspec"
|
19
|
+
# end
|
data/delayer.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = %q{Delay the processing}
|
13
13
|
spec.homepage = "https://github.com/toshia/delayer"
|
14
14
|
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = '>= 2.
|
15
|
+
spec.required_ruby_version = '>= 2.6.0'
|
16
16
|
|
17
17
|
spec.files = `git ls-files`.split($/)
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
data/lib/delayer.rb
CHANGED
@@ -3,6 +3,7 @@ require "delayer/version"
|
|
3
3
|
require "delayer/error"
|
4
4
|
require "delayer/extend"
|
5
5
|
require "delayer/procedure"
|
6
|
+
require "delayer/delayed_procedure"
|
6
7
|
require "monitor"
|
7
8
|
|
8
9
|
module Delayer
|
@@ -23,7 +24,7 @@ module Delayer
|
|
23
24
|
include ::Delayer
|
24
25
|
@expire = options[:expire] || 0
|
25
26
|
if options.has_key?(:priority)
|
26
|
-
@priorities = options[:priority]
|
27
|
+
@priorities = options[:priority].to_a.freeze
|
27
28
|
@default_priority = options[:default]
|
28
29
|
else
|
29
30
|
@priorities = [:normal]
|
@@ -32,11 +33,11 @@ module Delayer
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
def method_missing(*args, **kwrest, &proc)
|
36
|
+
def method_missing(fn, *args, **kwrest, &proc)
|
36
37
|
if kwrest.empty?
|
37
|
-
(@default ||= generate_class).__send__(*args, &proc)
|
38
|
+
(@default ||= generate_class).__send__(fn, *args, &proc)
|
38
39
|
else
|
39
|
-
(@default ||= generate_class).__send__(*args, **kwrest, &proc)
|
40
|
+
(@default ||= generate_class).__send__(fn, *args, **kwrest, &proc)
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Delayer
|
4
|
+
class DelayedProcedure
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
attr_reader :state, :delayer, :reserve_at
|
8
|
+
def initialize(delayer, delay:, &proc)
|
9
|
+
@delayer = delayer
|
10
|
+
@proc = proc
|
11
|
+
case delay
|
12
|
+
when Time
|
13
|
+
@reserve_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + delay.to_f - Time.now.to_f
|
14
|
+
else
|
15
|
+
@reserve_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + delay.to_f
|
16
|
+
end
|
17
|
+
@cancel = false
|
18
|
+
@procedure = nil
|
19
|
+
@delayer.class.reserve(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def register
|
23
|
+
if !canceled?
|
24
|
+
@procedure = Procedure.new(@delayer, &@proc)
|
25
|
+
end
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def <=>(other)
|
30
|
+
@reserve_at <=> other.reserve_at
|
31
|
+
end
|
32
|
+
|
33
|
+
# Cancel this job
|
34
|
+
# ==== Exception
|
35
|
+
# Delayer::TooLate :: if already called run()
|
36
|
+
# ==== Return
|
37
|
+
# self
|
38
|
+
def cancel
|
39
|
+
@procedure&.cancel
|
40
|
+
@cancel = true
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return true if canceled this task
|
45
|
+
# ==== Return
|
46
|
+
# true if canceled this task
|
47
|
+
def canceled?
|
48
|
+
procedure = @procedure
|
49
|
+
if procedure
|
50
|
+
procedure.canceled?
|
51
|
+
else
|
52
|
+
@cancel
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/delayer/error.rb
CHANGED
data/lib/delayer/extend.rb
CHANGED
@@ -1,12 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
module Delayer
|
4
6
|
attr_reader :priority
|
5
7
|
|
6
|
-
Bucket
|
8
|
+
class Bucket
|
9
|
+
attr_accessor :first, :last, :priority_of, :stashed
|
10
|
+
|
11
|
+
def initialize(first, last, priority_of, stashed)
|
12
|
+
@first = first
|
13
|
+
@last = last
|
14
|
+
@priority_of = priority_of
|
15
|
+
@stashed = stashed
|
16
|
+
end
|
17
|
+
|
7
18
|
def stash_size
|
8
|
-
|
9
|
-
|
19
|
+
s = stashed
|
20
|
+
if s
|
21
|
+
1 + s.stash_size
|
10
22
|
else
|
11
23
|
0
|
12
24
|
end
|
@@ -19,10 +31,14 @@ module Delayer
|
|
19
31
|
end
|
20
32
|
end
|
21
33
|
|
22
|
-
def initialize(priority = self.class.instance_eval { @default_priority }, *_args, &proc)
|
34
|
+
def initialize(priority = self.class.instance_eval { @default_priority }, *_args, delay: 0, &proc)
|
23
35
|
self.class.validate_priority priority
|
24
36
|
@priority = priority
|
25
|
-
|
37
|
+
if delay == 0
|
38
|
+
@procedure = Procedure.new(self, &proc)
|
39
|
+
else
|
40
|
+
@procedure = DelayedProcedure.new(self, delay: delay, &proc)
|
41
|
+
end
|
26
42
|
end
|
27
43
|
|
28
44
|
# Cancel this job
|
@@ -46,8 +62,22 @@ module Delayer
|
|
46
62
|
@remain_hook = nil
|
47
63
|
@exception = nil
|
48
64
|
@remain_received = false
|
49
|
-
@lock =
|
65
|
+
@lock = Monitor.new
|
50
66
|
@bucket = Bucket.new(nil, nil, {}, nil)
|
67
|
+
@last_reserve = nil
|
68
|
+
@reserves = Set.new
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def pop_reserve(start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC))
|
73
|
+
if @last_reserve&.reserve_at&.<=(start_time)
|
74
|
+
lock.synchronize do
|
75
|
+
while @last_reserve&.reserve_at&.<=(start_time)
|
76
|
+
@last_reserve.register
|
77
|
+
@last_reserve = @reserves.min
|
78
|
+
@reserves.delete(@last_reserve)
|
79
|
+
end
|
80
|
+
end
|
51
81
|
end
|
52
82
|
end
|
53
83
|
|
@@ -57,11 +87,13 @@ module Delayer
|
|
57
87
|
# ==== Return
|
58
88
|
# self
|
59
89
|
def run(current_expire = @expire)
|
90
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_f
|
91
|
+
pop_reserve(start_time)
|
60
92
|
if current_expire == 0
|
61
|
-
|
93
|
+
run_once_without_pop_reserve until empty?
|
62
94
|
else
|
63
|
-
@end_time =
|
64
|
-
|
95
|
+
@end_time = end_time = start_time + @expire
|
96
|
+
run_once_without_pop_reserve while !empty? && (end_time >= Process.clock_gettime(Process::CLOCK_MONOTONIC))
|
65
97
|
@end_time = nil
|
66
98
|
end
|
67
99
|
if @remain_hook
|
@@ -74,22 +106,25 @@ module Delayer
|
|
74
106
|
end
|
75
107
|
|
76
108
|
def expire?
|
77
|
-
|
78
|
-
@end_time < Time.new.to_f
|
79
|
-
else
|
80
|
-
false
|
81
|
-
end
|
109
|
+
!!@end_time&.<(Time.new.to_f)
|
82
110
|
end
|
83
111
|
|
84
112
|
# Run a job and forward pointer.
|
85
113
|
# ==== Return
|
86
114
|
# self
|
87
115
|
def run_once
|
116
|
+
pop_reserve
|
117
|
+
run_once_without_pop_reserve
|
118
|
+
end
|
119
|
+
|
120
|
+
private def run_once_without_pop_reserve
|
88
121
|
if @bucket.first
|
89
122
|
@busy = true
|
90
123
|
procedure = forward
|
91
|
-
procedure = forward while @bucket.first && procedure
|
92
|
-
procedure
|
124
|
+
procedure = forward while @bucket.first && procedure&.canceled?
|
125
|
+
if procedure && !procedure.canceled?
|
126
|
+
procedure.run
|
127
|
+
end
|
93
128
|
end
|
94
129
|
ensure
|
95
130
|
@busy = false
|
@@ -146,6 +181,29 @@ module Delayer
|
|
146
181
|
self
|
147
182
|
end
|
148
183
|
|
184
|
+
# Register reserved job.
|
185
|
+
# It does not execute immediately.
|
186
|
+
# it calls register() in _procedure.reserve_at_.
|
187
|
+
# ==== Args
|
188
|
+
# [procedure] job(Delayer::DelayedProcedure)
|
189
|
+
# ==== Return
|
190
|
+
# self
|
191
|
+
def reserve(procedure)
|
192
|
+
lock.synchronize do
|
193
|
+
if @last_reserve
|
194
|
+
if @last_reserve > procedure
|
195
|
+
@reserves.add(@last_reserve)
|
196
|
+
@last_reserve = procedure
|
197
|
+
else
|
198
|
+
@reserves.add(procedure)
|
199
|
+
end
|
200
|
+
else
|
201
|
+
@last_reserve = procedure
|
202
|
+
end
|
203
|
+
end
|
204
|
+
self
|
205
|
+
end
|
206
|
+
|
149
207
|
def register_remain_hook(&proc)
|
150
208
|
@remain_hook = proc
|
151
209
|
end
|
@@ -154,8 +212,10 @@ module Delayer
|
|
154
212
|
if @bucket.priority_of[priority]
|
155
213
|
@bucket.priority_of[priority]
|
156
214
|
else
|
157
|
-
|
158
|
-
|
215
|
+
@priorities.index(priority)&.yield_self do |index|
|
216
|
+
next_index = index - 1
|
217
|
+
get_prev_point @priorities[next_index] if next_index >= 0
|
218
|
+
end
|
159
219
|
end
|
160
220
|
end
|
161
221
|
|
@@ -178,10 +238,11 @@ module Delayer
|
|
178
238
|
# [Delayer::NoLowerLevelError] stash_enter!が呼ばれていない時
|
179
239
|
# [Delayer::RemainJobsError] ジョブが残っているのにこのメソッドを呼んだ時
|
180
240
|
def stash_exit!
|
181
|
-
|
241
|
+
stashed = @bucket.stashed
|
242
|
+
raise Delayer::NoLowerLevelError, 'stash_exit! called in level 0.' unless stashed
|
182
243
|
raise Delayer::RemainJobsError, 'Current level has remain jobs. It must be empty current level jobs in call this method.' unless empty?
|
183
244
|
|
184
|
-
@bucket =
|
245
|
+
@bucket = stashed
|
185
246
|
end
|
186
247
|
|
187
248
|
# 現在のDelayer Stashレベルを返す。
|
@@ -194,10 +255,11 @@ module Delayer
|
|
194
255
|
def forward
|
195
256
|
lock.synchronize do
|
196
257
|
prev = @bucket.first
|
197
|
-
|
198
|
-
@bucket.
|
258
|
+
raise 'Current bucket not found' unless prev
|
259
|
+
nex = @bucket.first = prev.next
|
260
|
+
@bucket.last = nil unless nex
|
199
261
|
@bucket.priority_of.each do |priority, pointer|
|
200
|
-
@bucket.priority_of[priority] =
|
262
|
+
@bucket.priority_of[priority] = nex if prev == pointer
|
201
263
|
end
|
202
264
|
prev.next = nil
|
203
265
|
prev
|
data/lib/delayer/procedure.rb
CHANGED
data/lib/delayer/version.rb
CHANGED
data/sig/delayer.rbs
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# TypeProf 0.13.0
|
2
|
+
|
3
|
+
# Classes
|
4
|
+
module Delayer
|
5
|
+
type clock = Float | Integer | Rational
|
6
|
+
|
7
|
+
VERSION: String
|
8
|
+
extend Extend
|
9
|
+
extend Delayer
|
10
|
+
self.@expire: clock
|
11
|
+
self.@priorities: Array[Symbol]
|
12
|
+
self.@default_priority: Symbol
|
13
|
+
self.@default: singleton(Delayer)
|
14
|
+
@procedure: Procedure | DelayedProcedure
|
15
|
+
self.@busy: bool
|
16
|
+
self.@remain_hook: ^() -> void
|
17
|
+
self.@exception: Exception?
|
18
|
+
self.@remain_received: bool
|
19
|
+
self.@lock: Monitor
|
20
|
+
self.@bucket: Bucket
|
21
|
+
self.@last_reserve: nil
|
22
|
+
self.@reserves: untyped
|
23
|
+
@default_priority: Symbol
|
24
|
+
self.@end_time: clock?
|
25
|
+
|
26
|
+
class GeneratedDelayerAbstract
|
27
|
+
include ::Delayer
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.generate_class: (?Hash[Symbol,Integer|Symbol|Enumerable[Symbol]] options) -> singleton(Delayer)
|
31
|
+
def self.method_missing: (Symbol, *untyped, **untyped) { (*untyped) -> untyped } -> untyped
|
32
|
+
|
33
|
+
def self.StateError: (:cancel) -> singleton(AlreadyCanceledError)
|
34
|
+
| (:done) -> singleton(AlreadyExecutedError)
|
35
|
+
| (:run) -> singleton(AlreadyRunningError)
|
36
|
+
| (Symbol) -> singleton(TooLate)
|
37
|
+
|
38
|
+
attr_reader priority: Symbol
|
39
|
+
def self.included: (singleton(Delayer) klass) -> void
|
40
|
+
def initialize: (?untyped priority, *untyped _args, ?delay: Time | clock) -> void
|
41
|
+
def cancel: -> Delayer
|
42
|
+
def stash_size: -> (Integer)
|
43
|
+
def __send__: (Symbol, *untyped, **untyped) { (untyped) -> untyped } -> untyped
|
44
|
+
|
45
|
+
class DelayedProcedure
|
46
|
+
include Comparable
|
47
|
+
@proc: (^() -> void)
|
48
|
+
@cancel: bool
|
49
|
+
@procedure: Procedure?
|
50
|
+
|
51
|
+
attr_reader state: untyped
|
52
|
+
attr_reader delayer: Delayer
|
53
|
+
attr_reader reserve_at: clock
|
54
|
+
def initialize: (Delayer delayer, delay: Time | clock) { () -> void } -> void
|
55
|
+
def register: -> self
|
56
|
+
def <=>: (DelayedProcedure other) -> Integer?
|
57
|
+
def cancel: -> self
|
58
|
+
def canceled?: -> bool
|
59
|
+
end
|
60
|
+
|
61
|
+
class Error < StandardError
|
62
|
+
end
|
63
|
+
|
64
|
+
class TooLate < Error
|
65
|
+
end
|
66
|
+
|
67
|
+
class AlreadyExecutedError < TooLate
|
68
|
+
end
|
69
|
+
|
70
|
+
class AlreadyCanceledError < TooLate
|
71
|
+
end
|
72
|
+
|
73
|
+
class AlreadyRunningError < TooLate
|
74
|
+
end
|
75
|
+
|
76
|
+
class InvalidPriorityError < Error
|
77
|
+
end
|
78
|
+
|
79
|
+
class RecursiveError < Error
|
80
|
+
end
|
81
|
+
|
82
|
+
class NoLowerLevelError < RecursiveError
|
83
|
+
end
|
84
|
+
|
85
|
+
class RemainJobsError < RecursiveError
|
86
|
+
end
|
87
|
+
|
88
|
+
class Bucket
|
89
|
+
attr_accessor first(): Procedure?
|
90
|
+
attr_accessor last(): Procedure?
|
91
|
+
attr_accessor priority_of(): Hash[Symbol, Procedure?]
|
92
|
+
attr_accessor stashed(): Bucket?
|
93
|
+
|
94
|
+
def initialize: (Procedure?,Procedure?,Hash[Symbol, Procedure],Bucket?) -> void
|
95
|
+
def stash_size: () -> Integer
|
96
|
+
end
|
97
|
+
|
98
|
+
module Extend
|
99
|
+
@last_reserve: untyped
|
100
|
+
@lock: Monitor
|
101
|
+
@end_time: clock?
|
102
|
+
@bucket: Bucket
|
103
|
+
@remain_hook: ^() -> void
|
104
|
+
@remain_received: bool
|
105
|
+
@busy: bool
|
106
|
+
@priorities: Array[Symbol]
|
107
|
+
@reserves: Set[DelayedProcedure]
|
108
|
+
|
109
|
+
attr_accessor expire: clock
|
110
|
+
attr_reader exception: Exception?
|
111
|
+
def self.extended: (singleton(Delayer) klass) -> singleton(Delayer)
|
112
|
+
def pop_reserve: (?clock start_time) -> nil
|
113
|
+
def run: (?clock? current_expire) -> void
|
114
|
+
def expire?: -> bool
|
115
|
+
def run_once: -> void
|
116
|
+
|
117
|
+
private
|
118
|
+
def run_once_without_pop_reserve: -> void
|
119
|
+
|
120
|
+
public
|
121
|
+
def busy?: -> bool
|
122
|
+
def empty?: -> bool
|
123
|
+
def size: (?Delayer::Procedure? node) -> Integer
|
124
|
+
def register: (untyped procedure) -> Extend
|
125
|
+
def reserve: (untyped procedure) -> Extend
|
126
|
+
def register_remain_hook: () { () -> void } -> void
|
127
|
+
def get_prev_point: (Symbol) -> ::Delayer::Procedure?
|
128
|
+
def validate_priority: (Symbol) -> void
|
129
|
+
def stash_enter!: -> Extend
|
130
|
+
def stash_exit!: -> Bucket?
|
131
|
+
def stash_level: -> untyped
|
132
|
+
|
133
|
+
private
|
134
|
+
def forward: -> Procedure?
|
135
|
+
def lock: -> Monitor
|
136
|
+
end
|
137
|
+
|
138
|
+
class Procedure
|
139
|
+
@proc: (^() -> void)?
|
140
|
+
|
141
|
+
attr_reader state: :cancel | :done | :run | :stop
|
142
|
+
attr_reader delayer: untyped
|
143
|
+
attr_accessor next: Delayer::Procedure?
|
144
|
+
def initialize: (Delayer delayer) { () -> void } -> void
|
145
|
+
def run: -> void
|
146
|
+
def cancel: -> Procedure
|
147
|
+
def canceled?: -> bool
|
148
|
+
def break: (untyped node) -> untyped
|
149
|
+
end
|
150
|
+
end
|
data/test/test_delayer.rb
CHANGED
@@ -353,4 +353,112 @@ class TestDelayer < Test::Unit::TestCase
|
|
353
353
|
end
|
354
354
|
end
|
355
355
|
|
356
|
+
def test_timer
|
357
|
+
delayer = Delayer.generate_class expire: 0.01
|
358
|
+
a = []
|
359
|
+
delayer.new(delay: 0.01) { a << 0 }
|
360
|
+
delayer.new { a << 1 }
|
361
|
+
|
362
|
+
delayer.run
|
363
|
+
|
364
|
+
delayer.new { a << 2 }
|
365
|
+
sleep 0.1
|
366
|
+
|
367
|
+
delayer.run
|
368
|
+
|
369
|
+
delayer.new { a << 3 }
|
370
|
+
|
371
|
+
delayer.run
|
372
|
+
|
373
|
+
assert_equal([1, 2, 0, 3], a)
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_timer_give_time
|
377
|
+
delayer = Delayer.generate_class expire: 0.01
|
378
|
+
a = []
|
379
|
+
delayer.new(delay: Time.new) { a << 0 }
|
380
|
+
|
381
|
+
delayer.run
|
382
|
+
|
383
|
+
assert_equal([0], a)
|
384
|
+
end
|
385
|
+
|
386
|
+
def test_plural_timer
|
387
|
+
delayer = Delayer.generate_class expire: 0.01
|
388
|
+
a = []
|
389
|
+
delayer.new(delay: 0.01) { a << 0 }
|
390
|
+
delayer.new(delay: 0.11) { a << 1 }
|
391
|
+
delayer.new { a << 2 }
|
392
|
+
|
393
|
+
delayer.run
|
394
|
+
|
395
|
+
delayer.new { a << 3 }
|
396
|
+
sleep 0.1
|
397
|
+
|
398
|
+
delayer.run
|
399
|
+
sleep 0.1
|
400
|
+
|
401
|
+
delayer.new { a << 4 }
|
402
|
+
|
403
|
+
delayer.run
|
404
|
+
|
405
|
+
assert_equal([2, 3, 0, 4, 1], a)
|
406
|
+
end
|
407
|
+
|
408
|
+
def test_many_timer
|
409
|
+
delayer = Delayer.generate_class expire: 0.01
|
410
|
+
a = []
|
411
|
+
(0..10).to_a.shuffle.each do |i|
|
412
|
+
delayer.new(delay: i / 100.0) { a << i }
|
413
|
+
end
|
414
|
+
|
415
|
+
sleep 0.1
|
416
|
+
|
417
|
+
delayer.run
|
418
|
+
|
419
|
+
assert_equal((0..10).to_a, a)
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_cancel_timer
|
423
|
+
delayer = Delayer.generate_class
|
424
|
+
a = 0
|
425
|
+
delayer.new(delay: 0.01) { a += 1 }
|
426
|
+
d = delayer.new(delay: 0.01) { a += 2 }
|
427
|
+
delayer.new(delay: 0.01) { a += 4 }
|
428
|
+
|
429
|
+
assert_equal(0, a)
|
430
|
+
d.cancel
|
431
|
+
sleep 0.1
|
432
|
+
delayer.run
|
433
|
+
assert_equal(5, a)
|
434
|
+
end
|
435
|
+
|
436
|
+
def test_cancel_timer_after_expire
|
437
|
+
delayer = Delayer.generate_class
|
438
|
+
a = 0
|
439
|
+
delayer.new(delay: 0.01) { a += 1 }
|
440
|
+
d = delayer.new(delay: 0.01) { a += 2 }
|
441
|
+
delayer.new{ d.cancel }
|
442
|
+
delayer.new(delay: 0.01) { a += 4 }
|
443
|
+
|
444
|
+
assert_equal(0, a)
|
445
|
+
sleep 0.1
|
446
|
+
delayer.run
|
447
|
+
assert_equal(5, a)
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_reserve_new_timer_after_cancel
|
451
|
+
delayer = Delayer.generate_class
|
452
|
+
a = 0
|
453
|
+
delayer.new(delay: 0.01) { a += 1 }
|
454
|
+
d = delayer.new(delay: 0.02) { a += 2 }
|
455
|
+
d.cancel
|
456
|
+
delayer.new(delay: 0.03) { a += 4 }
|
457
|
+
|
458
|
+
assert_equal(0, a)
|
459
|
+
sleep 0.1
|
460
|
+
delayer.run
|
461
|
+
assert_equal(5, a)
|
462
|
+
end
|
463
|
+
|
356
464
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delayer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toshiaki Asai
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -71,19 +71,22 @@ files:
|
|
71
71
|
- LICENSE.txt
|
72
72
|
- README.md
|
73
73
|
- Rakefile
|
74
|
+
- Steepfile
|
74
75
|
- delayer.gemspec
|
75
76
|
- lib/delayer.rb
|
77
|
+
- lib/delayer/delayed_procedure.rb
|
76
78
|
- lib/delayer/error.rb
|
77
79
|
- lib/delayer/extend.rb
|
78
80
|
- lib/delayer/procedure.rb
|
79
81
|
- lib/delayer/version.rb
|
82
|
+
- sig/delayer.rbs
|
80
83
|
- test/test_delayer.rb
|
81
84
|
- test/test_priority.rb
|
82
85
|
homepage: https://github.com/toshia/delayer
|
83
86
|
licenses:
|
84
87
|
- MIT
|
85
88
|
metadata: {}
|
86
|
-
post_install_message:
|
89
|
+
post_install_message:
|
87
90
|
rdoc_options: []
|
88
91
|
require_paths:
|
89
92
|
- lib
|
@@ -91,15 +94,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
94
|
requirements:
|
92
95
|
- - ">="
|
93
96
|
- !ruby/object:Gem::Version
|
94
|
-
version: 2.
|
97
|
+
version: 2.6.0
|
95
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
99
|
requirements:
|
97
100
|
- - ">="
|
98
101
|
- !ruby/object:Gem::Version
|
99
102
|
version: '0'
|
100
103
|
requirements: []
|
101
|
-
rubygems_version: 3.
|
102
|
-
signing_key:
|
104
|
+
rubygems_version: 3.2.15
|
105
|
+
signing_key:
|
103
106
|
specification_version: 4
|
104
107
|
summary: Delay the processing
|
105
108
|
test_files:
|