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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f45ebc21cd1a3e765702c2bc30e1a6244fbc0ab5b6568dd7152ea4f3c7bdc993
4
- data.tar.gz: 70386ae1784b5bcc7ce417e02879dd12723a61f3b8e6100dd281093d50787d47
3
+ metadata.gz: 003a08fd66333486ef3f6512418dbffb7141a8e8f2d172b0c6ab0f3ce60f439c
4
+ data.tar.gz: b5dc15813a92615447be5651e301e5741196b63e545bdb56d1b68b718e46eec7
5
5
  SHA512:
6
- metadata.gz: f451adec9a6f7eb037c15ce348d3dd897e0f68bb8c496c00435cd4d09c9757794c725eb1964b9694bc355ecc85f3e0ae2899a94e06a83b2a54cd03819ae130f7
7
- data.tar.gz: 0a430ec5704743c416a1d5cf900378062ec5bbe22dcac0458e69c0b9cf28fb0eed2c903849c18830250e341484a9ed54da2ea80286cb54744cd7c61977b28009
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.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
@@ -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
@@ -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
@@ -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 = Struct.new(:first, :last, :priority_of, :stashed) do
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
- if stashed
9
- 1 + stashed.stash_size
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
- @procedure = Procedure.new(self, &proc)
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 = Mutex.new
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
- run_once until empty?
93
+ run_once_without_pop_reserve until empty?
62
94
  else
63
- @end_time = Time.new.to_f + @expire
64
- run_once while !empty? && (@end_time >= Time.new.to_f)
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
- if defined?(@end_time) && @end_time
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.canceled?
92
- procedure.run unless procedure.canceled?
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
- next_index = @priorities.index(priority) - 1
158
- get_prev_point @priorities[next_index] if next_index >= 0
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
- raise Delayer::NoLowerLevelError, 'stash_exit! called in level 0.' unless @bucket.stashed
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 = @bucket.stashed
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
- @bucket.first = @bucket.first.next
198
- @bucket.last = nil unless @bucket.first
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] = @bucket.first if prev == pointer
262
+ @bucket.priority_of[priority] = nex if prev == pointer
201
263
  end
202
264
  prev.next = nil
203
265
  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.0.2'
4
+ VERSION = '1.2.1'
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
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.0.2
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: 2020-01-12 00:00:00.000000000 Z
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.4.0
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.1.2
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: