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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00c64707cef5f0715d026e9966b1a9d0b7e9676cad1882f73a145574f27d6352
4
- data.tar.gz: ac42bd9584e379c7d565eca7a79ef168266480dcf9594dee461d119e46b3066b
3
+ metadata.gz: e7fea45fe078293c50cf946662ce8aace4acf2aa40b30abf894cedf117473b30
4
+ data.tar.gz: d4f0e01ce8dfce355d90022b73431d695061d6bff5fe15280d47c95b3b60f28f
5
5
  SHA512:
6
- metadata.gz: d94ccb45deebd4d2c16d0f96e107da98297c53d691a1c9ebf9eb6c234e327b9e72da07576e6d3b024969dce8e3ace8ecd9366cfb9b8a65e257994b3fdd5d4765
7
- data.tar.gz: c208b40f6e1e0166aea86ab71c25b1fdb74e8412771724ac008800173eebb7396bea0c4c3665afc38e672cdd4a5fa2828aa05645eb6a27c9c909a76a581821d6
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.5'
34
+ ruby-version: '2.6.7'
38
35
  - build:
39
36
  name: 'ruby-2.7'
40
- ruby-version: '2.7.0'
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.4.0'
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 = nil
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
- if @procedure
39
- @procedure.cancel
40
- else
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
- if @procedure
50
- @procedure.canceled?
48
+ procedure = @procedure
49
+ if procedure
50
+ procedure.canceled?
51
51
  else
52
52
  @cancel
53
53
  end
data/lib/delayer/error.rb CHANGED
@@ -20,6 +20,8 @@ module Delayer
20
20
  AlreadyExecutedError
21
21
  when :cancel
22
22
  AlreadyCanceledError
23
+ else
24
+ TooLate
23
25
  end
24
26
  end
25
27
  end
@@ -3,10 +3,20 @@
3
3
  module Delayer
4
4
  attr_reader :priority
5
5
 
6
- Bucket = Struct.new(:first, :last, :priority_of, :stashed) do
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
- if stashed
9
- 1 + stashed.stash_size
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? && (@end_time >= Process.clock_gettime(Process::CLOCK_MONOTONIC))
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
- if defined?(@end_time) && @end_time
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.canceled?
117
- procedure.run unless procedure.canceled?
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
- next_index = @priorities.index(priority) - 1
206
- get_prev_point @priorities[next_index] if next_index >= 0
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
- raise Delayer::NoLowerLevelError, 'stash_exit! called in level 0.' unless @bucket.stashed
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 = @bucket.stashed
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
- @bucket.first = @bucket.first.next
246
- @bucket.last = nil unless @bucket.first
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] = @bucket.first if prev == pointer
260
+ @bucket.priority_of[priority] = nex if prev == pointer
249
261
  end
250
262
  prev.next = nil
251
263
  prev
@@ -23,7 +23,7 @@ module Delayer
23
23
  end
24
24
 
25
25
  @state = :run
26
- @proc.call
26
+ @proc&.call
27
27
  @state = :done
28
28
  @proc = nil
29
29
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayer
4
- VERSION = '1.1.2'
4
+ VERSION = '1.2.0'
5
5
  end
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.1.2
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: 2020-01-12 00:00:00.000000000 Z
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.4.0
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.1.2
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: