evt-wait 2.0.1.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 +7 -0
- data/lib/wait/controls/time.rb +5 -0
- data/lib/wait/controls.rb +3 -0
- data/lib/wait/log.rb +9 -0
- data/lib/wait/wait.rb +169 -0
- data/lib/wait.rb +6 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bca2702e59c02ee267536fcdef906db0bb76d5c2eddc64abbd6cbec0f0057731
|
4
|
+
data.tar.gz: 2b571bae744dad9731a0c90b35e417199603d3d29c7dcde17728b8fb2c6bdada
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc83aa97f8703d2f68fae17bec1d99801df345d9743d57cb88e46062fe77f24fb805f05a394a3c8cc819ec83f618d13972a095477398904552cdabb5d2a86b98
|
7
|
+
data.tar.gz: 8ec8d89999fc8816510af933c73bdd5384a78bb91252bd1da0581ac877f65dbf9bb5c77b50a427a6a255b6de30f83d364e185f565859c08cbed19efa1119d4d9
|
data/lib/wait/log.rb
ADDED
data/lib/wait/wait.rb
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
class Wait
|
2
|
+
Error = Class.new(RuntimeError)
|
3
|
+
NoBlockError = Class.new(Error)
|
4
|
+
TimeoutError = Class.new(Error)
|
5
|
+
ResultTypeError = Class.new(Error)
|
6
|
+
|
7
|
+
include Dependency
|
8
|
+
include Log::Dependency
|
9
|
+
|
10
|
+
dependency :clock, Clock::UTC
|
11
|
+
dependency :telemetry, Telemetry
|
12
|
+
|
13
|
+
def self.build
|
14
|
+
instance = new
|
15
|
+
instance.configure
|
16
|
+
instance
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.configure(receiver, attr_name: nil)
|
20
|
+
attr_name ||= :wait
|
21
|
+
instance = build
|
22
|
+
receiver.public_send("#{attr_name}=", instance)
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure
|
26
|
+
Clock::UTC.configure(self)
|
27
|
+
::Telemetry.configure(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.call(interval_milliseconds: nil, timeout_milliseconds: nil, &condition)
|
31
|
+
instance = build
|
32
|
+
instance.call(interval_milliseconds: interval_milliseconds, timeout_milliseconds: timeout_milliseconds, &condition)
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(interval_milliseconds: nil, timeout_milliseconds: nil, &condition)
|
36
|
+
interval_milliseconds ||= Defaults.interval_milliseconds
|
37
|
+
|
38
|
+
if condition.nil?
|
39
|
+
raise NoBlockError, "Wait must be actuated with a block"
|
40
|
+
end
|
41
|
+
|
42
|
+
stop_time = nil
|
43
|
+
stop_time_iso8601 = nil
|
44
|
+
if not timeout_milliseconds.nil?
|
45
|
+
stop_time = clock.now + (timeout_milliseconds.to_f / 1000.0)
|
46
|
+
stop_time_iso8601 = clock.iso8601(stop_time, precision: 5)
|
47
|
+
end
|
48
|
+
|
49
|
+
logger.trace { "Cycling (Interval Milliseconds: #{interval_milliseconds.inspect}, Timeout Milliseconds: #{timeout_milliseconds.inspect}, Stop Time: #{stop_time_iso8601.inspect})" }
|
50
|
+
|
51
|
+
cycle = -1
|
52
|
+
result = nil
|
53
|
+
loop do
|
54
|
+
cycle += 1
|
55
|
+
telemetry.record(:cycle, cycle)
|
56
|
+
|
57
|
+
result, elapsed_milliseconds = evaluate_condition(cycle, &condition)
|
58
|
+
|
59
|
+
if result.nil?
|
60
|
+
result = false
|
61
|
+
end
|
62
|
+
|
63
|
+
if not (result.is_a?(TrueClass) || result.is_a?(FalseClass))
|
64
|
+
raise ResultTypeError, "The block result must be boolean (Result: #{result.inspect})"
|
65
|
+
end
|
66
|
+
|
67
|
+
if result == true
|
68
|
+
logger.debug { "Cycle condition is met (Cycle: #{cycle})" }
|
69
|
+
telemetry.record(:condition_satisfied)
|
70
|
+
break
|
71
|
+
end
|
72
|
+
|
73
|
+
delay(interval_milliseconds, elapsed_milliseconds)
|
74
|
+
|
75
|
+
if !timeout_milliseconds.nil?
|
76
|
+
now = clock.now
|
77
|
+
if now >= stop_time
|
78
|
+
logger.debug { "Timeout has lapsed (Cycle: #{cycle}, Stop Time: #{stop_time_iso8601}, Timeout Milliseconds: #{timeout_milliseconds.inspect})" }
|
79
|
+
telemetry.record(:timed_out, now)
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
logger.debug { "Cycled (Cycles: #{cycle + 1}, Interval Milliseconds: #{interval_milliseconds.inspect}, Timeout Milliseconds: #{timeout_milliseconds.inspect}, Stop Time: #{stop_time_iso8601})" }
|
86
|
+
|
87
|
+
cycle_count = cycle + 1
|
88
|
+
|
89
|
+
return cycle_count
|
90
|
+
end
|
91
|
+
|
92
|
+
def evaluate_condition(cycle, &condition)
|
93
|
+
condition_start_time = clock.now
|
94
|
+
|
95
|
+
logger.trace { "Evaluating condition (Cycle: #{cycle}, Start Time: #{clock.iso8601(condition_start_time, precision: 5)})" }
|
96
|
+
|
97
|
+
result = condition.call(cycle)
|
98
|
+
|
99
|
+
condition_end_time = clock.now
|
100
|
+
elapsed_milliseconds = clock.elapsed_milliseconds(condition_start_time, condition_end_time)
|
101
|
+
|
102
|
+
logger.debug { "Evaluated condition (Cycle: #{cycle}, Elapsed Milliseconds: #{elapsed_milliseconds}, Start Time: #{clock.iso8601(condition_start_time, precision: 5)}, End Time: #{clock.iso8601(condition_end_time, precision: 5)})" }
|
103
|
+
|
104
|
+
[result, elapsed_milliseconds]
|
105
|
+
end
|
106
|
+
|
107
|
+
def delay(interval_milliseconds, elapsed_milliseconds)
|
108
|
+
delay_milliseconds = interval_milliseconds - elapsed_milliseconds
|
109
|
+
|
110
|
+
logger.trace { "Delaying (Delay Milliseconds: #{delay_milliseconds}, Interval Milliseconds: #{interval_milliseconds}, Elapsed Milliseconds: #{elapsed_milliseconds})" }
|
111
|
+
|
112
|
+
if delay_milliseconds <= 0
|
113
|
+
logger.debug { "Elapsed time exceeds or equals interval. Not delayed. (Delay Milliseconds: #{delay_milliseconds}, Interval Milliseconds: #{interval_milliseconds}, Elapsed Milliseconds: #{elapsed_milliseconds})" }
|
114
|
+
return
|
115
|
+
end
|
116
|
+
|
117
|
+
delay_seconds = (delay_milliseconds.to_f / 1000.0)
|
118
|
+
|
119
|
+
sleep delay_seconds
|
120
|
+
|
121
|
+
telemetry.record(:delayed, delay_milliseconds)
|
122
|
+
|
123
|
+
logger.debug { "Finished delaying (Delay Milliseconds: #{delay_milliseconds}, Interval Milliseconds: #{interval_milliseconds}, Elapsed Milliseconds: #{elapsed_milliseconds})" }
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.register_telemetry_sink(cycle)
|
127
|
+
sink = Telemetry.sink
|
128
|
+
cycle.telemetry.register(sink)
|
129
|
+
sink
|
130
|
+
end
|
131
|
+
|
132
|
+
module Defaults
|
133
|
+
def self.interval_milliseconds
|
134
|
+
0
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
module Telemetry
|
139
|
+
class Sink
|
140
|
+
include ::Telemetry::Sink
|
141
|
+
|
142
|
+
record :cycle
|
143
|
+
record :condition_satisfied
|
144
|
+
record :delayed
|
145
|
+
record :timed_out
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.sink
|
149
|
+
Sink.new
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
module Substitute
|
154
|
+
def self.build
|
155
|
+
instance = Wait.build
|
156
|
+
|
157
|
+
sink = Wait.register_telemetry_sink(instance)
|
158
|
+
instance.telemetry_sink = sink
|
159
|
+
|
160
|
+
instance.configure
|
161
|
+
|
162
|
+
instance
|
163
|
+
end
|
164
|
+
|
165
|
+
class Wait < ::Wait
|
166
|
+
attr_accessor :telemetry_sink
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
data/lib/wait.rb
ADDED
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evt-wait
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- The Eventide Project
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-10-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: evt-log
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: evt-telemetry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: evt-clock
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: test_bench
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: " "
|
70
|
+
email: opensource@eventide-project.org
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- lib/wait.rb
|
76
|
+
- lib/wait/controls.rb
|
77
|
+
- lib/wait/controls/time.rb
|
78
|
+
- lib/wait/log.rb
|
79
|
+
- lib/wait/wait.rb
|
80
|
+
homepage: https://github.com/eventide-project/wait
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '2.4'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubygems_version: 3.3.3
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Generalized implementation of execution-until-condition with support for
|
103
|
+
timeout and polling interval
|
104
|
+
test_files: []
|