delayer 1.1.2 → 1.2.0
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 +4 -4
- data/lib/delayer/delayed_procedure.rb +8 -8
- data/lib/delayer/error.rb +2 -0
- data/lib/delayer/extend.rb +32 -20
- data/lib/delayer/procedure.rb +1 -1
- data/lib/delayer/version.rb +1 -1
- data/sig/delayer.rbs +150 -0
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7fea45fe078293c50cf946662ce8aace4acf2aa40b30abf894cedf117473b30
|
4
|
+
data.tar.gz: d4f0e01ce8dfce355d90022b73431d695061d6bff5fe15280d47c95b3b60f28f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27c1f3aca5d5e4745d341667d5ce2cdb3a032402b9fe94269017bb59535e70f6f97d00d3d4d68ddb7932d0bcb9dc13f9f3bf57a693c52fb06adc762b4d181b12
|
7
|
+
data.tar.gz: 8d80f9c8d5c06707d68f9df0017e6598a18212322c3065ffdf497e5ee5c427e703a83ea2c975bd8a66f6be3fd956171b109ee3ca44de71d933f98baeaebd0483
|
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
@@ -24,7 +24,7 @@ module Delayer
|
|
24
24
|
include ::Delayer
|
25
25
|
@expire = options[:expire] || 0
|
26
26
|
if options.has_key?(:priority)
|
27
|
-
@priorities = options[:priority]
|
27
|
+
@priorities = options[:priority].to_a.freeze
|
28
28
|
@default_priority = options[:default]
|
29
29
|
else
|
30
30
|
@priorities = [:normal]
|
@@ -33,11 +33,11 @@ module Delayer
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def method_missing(*args, **kwrest, &proc)
|
36
|
+
def method_missing(fn, *args, **kwrest, &proc)
|
37
37
|
if kwrest.empty?
|
38
|
-
(@default ||= generate_class).__send__(*args, &proc)
|
38
|
+
(@default ||= generate_class).__send__(fn, *args, &proc)
|
39
39
|
else
|
40
|
-
(@default ||= generate_class).__send__(*args, **kwrest, &proc)
|
40
|
+
(@default ||= generate_class).__send__(fn, *args, **kwrest, &proc)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -14,7 +14,7 @@ module Delayer
|
|
14
14
|
else
|
15
15
|
@reserve_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + delay.to_f
|
16
16
|
end
|
17
|
-
@cancel =
|
17
|
+
@cancel = false
|
18
18
|
@procedure = nil
|
19
19
|
@delayer.class.reserve(self)
|
20
20
|
end
|
@@ -23,6 +23,7 @@ module Delayer
|
|
23
23
|
if !canceled?
|
24
24
|
@procedure = Procedure.new(@delayer, &@proc)
|
25
25
|
end
|
26
|
+
self
|
26
27
|
end
|
27
28
|
|
28
29
|
def <=>(other)
|
@@ -35,19 +36,18 @@ module Delayer
|
|
35
36
|
# ==== Return
|
36
37
|
# self
|
37
38
|
def cancel
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
@cancel = true
|
42
|
-
end
|
39
|
+
@procedure&.cancel
|
40
|
+
@cancel = true
|
41
|
+
self
|
43
42
|
end
|
44
43
|
|
45
44
|
# Return true if canceled this task
|
46
45
|
# ==== Return
|
47
46
|
# true if canceled this task
|
48
47
|
def canceled?
|
49
|
-
|
50
|
-
|
48
|
+
procedure = @procedure
|
49
|
+
if procedure
|
50
|
+
procedure.canceled?
|
51
51
|
else
|
52
52
|
@cancel
|
53
53
|
end
|
data/lib/delayer/error.rb
CHANGED
data/lib/delayer/extend.rb
CHANGED
@@ -3,10 +3,20 @@
|
|
3
3
|
module Delayer
|
4
4
|
attr_reader :priority
|
5
5
|
|
6
|
-
Bucket
|
6
|
+
class Bucket
|
7
|
+
attr_accessor :first, :last, :priority_of, :stashed
|
8
|
+
|
9
|
+
def initialize(first, last, priority_of, stashed)
|
10
|
+
@first = first
|
11
|
+
@last = last
|
12
|
+
@priority_of = priority_of
|
13
|
+
@stashed = stashed
|
14
|
+
end
|
15
|
+
|
7
16
|
def stash_size
|
8
|
-
|
9
|
-
|
17
|
+
s = stashed
|
18
|
+
if s
|
19
|
+
1 + s.stash_size
|
10
20
|
else
|
11
21
|
0
|
12
22
|
end
|
@@ -75,13 +85,13 @@ module Delayer
|
|
75
85
|
# ==== Return
|
76
86
|
# self
|
77
87
|
def run(current_expire = @expire)
|
78
|
-
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
88
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_f
|
79
89
|
pop_reserve(start_time)
|
80
90
|
if current_expire == 0
|
81
91
|
run_once_without_pop_reserve until empty?
|
82
92
|
else
|
83
|
-
@end_time = start_time + @expire
|
84
|
-
run_once_without_pop_reserve while !empty? && (
|
93
|
+
@end_time = end_time = start_time + @expire
|
94
|
+
run_once_without_pop_reserve while !empty? && (end_time >= Process.clock_gettime(Process::CLOCK_MONOTONIC))
|
85
95
|
@end_time = nil
|
86
96
|
end
|
87
97
|
if @remain_hook
|
@@ -94,11 +104,7 @@ module Delayer
|
|
94
104
|
end
|
95
105
|
|
96
106
|
def expire?
|
97
|
-
|
98
|
-
@end_time < Time.new.to_f
|
99
|
-
else
|
100
|
-
false
|
101
|
-
end
|
107
|
+
!!@end_time&.<(Time.new.to_f)
|
102
108
|
end
|
103
109
|
|
104
110
|
# Run a job and forward pointer.
|
@@ -113,8 +119,10 @@ module Delayer
|
|
113
119
|
if @bucket.first
|
114
120
|
@busy = true
|
115
121
|
procedure = forward
|
116
|
-
procedure = forward while @bucket.first && procedure
|
117
|
-
procedure
|
122
|
+
procedure = forward while @bucket.first && procedure&.canceled?
|
123
|
+
if procedure && !procedure.canceled?
|
124
|
+
procedure.run
|
125
|
+
end
|
118
126
|
end
|
119
127
|
ensure
|
120
128
|
@busy = false
|
@@ -202,8 +210,10 @@ module Delayer
|
|
202
210
|
if @bucket.priority_of[priority]
|
203
211
|
@bucket.priority_of[priority]
|
204
212
|
else
|
205
|
-
|
206
|
-
|
213
|
+
@priorities.index(priority)&.yield_self do |index|
|
214
|
+
next_index = index - 1
|
215
|
+
get_prev_point @priorities[next_index] if next_index >= 0
|
216
|
+
end
|
207
217
|
end
|
208
218
|
end
|
209
219
|
|
@@ -226,10 +236,11 @@ module Delayer
|
|
226
236
|
# [Delayer::NoLowerLevelError] stash_enter!が呼ばれていない時
|
227
237
|
# [Delayer::RemainJobsError] ジョブが残っているのにこのメソッドを呼んだ時
|
228
238
|
def stash_exit!
|
229
|
-
|
239
|
+
stashed = @bucket.stashed
|
240
|
+
raise Delayer::NoLowerLevelError, 'stash_exit! called in level 0.' unless stashed
|
230
241
|
raise Delayer::RemainJobsError, 'Current level has remain jobs. It must be empty current level jobs in call this method.' unless empty?
|
231
242
|
|
232
|
-
@bucket =
|
243
|
+
@bucket = stashed
|
233
244
|
end
|
234
245
|
|
235
246
|
# 現在のDelayer Stashレベルを返す。
|
@@ -242,10 +253,11 @@ module Delayer
|
|
242
253
|
def forward
|
243
254
|
lock.synchronize do
|
244
255
|
prev = @bucket.first
|
245
|
-
|
246
|
-
@bucket.
|
256
|
+
raise 'Current bucket not found' unless prev
|
257
|
+
nex = @bucket.first = prev.next
|
258
|
+
@bucket.last = nil unless nex
|
247
259
|
@bucket.priority_of.each do |priority, pointer|
|
248
|
-
@bucket.priority_of[priority] =
|
260
|
+
@bucket.priority_of[priority] = nex if prev == pointer
|
249
261
|
end
|
250
262
|
prev.next = nil
|
251
263
|
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
|
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.0
|
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-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- LICENSE.txt
|
72
72
|
- README.md
|
73
73
|
- Rakefile
|
74
|
+
- Steepfile
|
74
75
|
- delayer.gemspec
|
75
76
|
- lib/delayer.rb
|
76
77
|
- lib/delayer/delayed_procedure.rb
|
@@ -78,13 +79,14 @@ files:
|
|
78
79
|
- lib/delayer/extend.rb
|
79
80
|
- lib/delayer/procedure.rb
|
80
81
|
- lib/delayer/version.rb
|
82
|
+
- sig/delayer.rbs
|
81
83
|
- test/test_delayer.rb
|
82
84
|
- test/test_priority.rb
|
83
85
|
homepage: https://github.com/toshia/delayer
|
84
86
|
licenses:
|
85
87
|
- MIT
|
86
88
|
metadata: {}
|
87
|
-
post_install_message:
|
89
|
+
post_install_message:
|
88
90
|
rdoc_options: []
|
89
91
|
require_paths:
|
90
92
|
- lib
|
@@ -92,15 +94,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
94
|
requirements:
|
93
95
|
- - ">="
|
94
96
|
- !ruby/object:Gem::Version
|
95
|
-
version: 2.
|
97
|
+
version: 2.6.0
|
96
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
99
|
requirements:
|
98
100
|
- - ">="
|
99
101
|
- !ruby/object:Gem::Version
|
100
102
|
version: '0'
|
101
103
|
requirements: []
|
102
|
-
rubygems_version: 3.
|
103
|
-
signing_key:
|
104
|
+
rubygems_version: 3.2.13
|
105
|
+
signing_key:
|
104
106
|
specification_version: 4
|
105
107
|
summary: Delay the processing
|
106
108
|
test_files:
|