evt-poll 0.1.0.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 +7 -0
- data/lib/poll.rb +7 -0
- data/lib/poll/controls.rb +3 -0
- data/lib/poll/controls/time.rb +5 -0
- data/lib/poll/cycle.rb +179 -0
- data/lib/poll/defaults.rb +17 -0
- data/lib/poll/log.rb +9 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 89cf5f449b8dcf01f48c82d39a139434ea8ac185c7178bac749c4394de174bf7
|
4
|
+
data.tar.gz: d24ea1791c7bf0400b32b33a83fa07963f700623ed3169dff10967ed417f18f3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0f875934c022770e5b14eed4b066326ec0c0faf60bb48d8e09450d508e72d20c398dbda654124a0337a8ca484c05ea16f9b1ae392fcac0f1b1220f8d821c55f7
|
7
|
+
data.tar.gz: ea00a5edf1896470713a6cb76cd516ae97f19a99e8832f7c54f63aa7cc2525b96521f2b976173d431119587c46c17eee8b7db3397e1aab98a41e35b74d163821
|
data/lib/poll.rb
ADDED
data/lib/poll/cycle.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
class Poll
|
2
|
+
Error = Class.new(RuntimeError)
|
3
|
+
|
4
|
+
include Log::Dependency
|
5
|
+
|
6
|
+
dependency :clock, Clock::UTC
|
7
|
+
dependency :telemetry, Telemetry
|
8
|
+
|
9
|
+
attr_writer :interval_milliseconds
|
10
|
+
def interval_milliseconds
|
11
|
+
@interval_milliseconds ||= Defaults.interval_milliseconds
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :timeout_milliseconds
|
15
|
+
|
16
|
+
attr_writer :delay_condition
|
17
|
+
def delay_condition
|
18
|
+
@delay_condition ||= Defaults.delay_condition
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.build(interval_milliseconds: nil, timeout_milliseconds: nil, delay_condition: nil)
|
22
|
+
instance = new
|
23
|
+
|
24
|
+
instance.interval_milliseconds = interval_milliseconds
|
25
|
+
instance.timeout_milliseconds = timeout_milliseconds
|
26
|
+
instance.delay_condition = delay_condition
|
27
|
+
|
28
|
+
instance.configure
|
29
|
+
|
30
|
+
instance
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.configure(receiver, attr_name: nil, interval_milliseconds: nil, timeout_milliseconds: nil, delay_condition: nil, cycle: nil)
|
34
|
+
attr_name ||= :cycle
|
35
|
+
|
36
|
+
if !cycle.nil?
|
37
|
+
instance = cycle
|
38
|
+
else
|
39
|
+
instance = build(interval_milliseconds: interval_milliseconds, timeout_milliseconds: timeout_milliseconds, delay_condition: delay_condition)
|
40
|
+
end
|
41
|
+
|
42
|
+
receiver.public_send "#{attr_name}=", instance
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.none
|
46
|
+
None.build
|
47
|
+
end
|
48
|
+
|
49
|
+
def configure
|
50
|
+
Clock::UTC.configure self
|
51
|
+
::Telemetry.configure self
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.call(interval_milliseconds: nil, timeout_milliseconds: nil, delay_condition: nil, &action)
|
55
|
+
instance = build(interval_milliseconds: interval_milliseconds, timeout_milliseconds: timeout_milliseconds, delay_condition: delay_condition)
|
56
|
+
instance.call(&action)
|
57
|
+
end
|
58
|
+
|
59
|
+
def call(&action)
|
60
|
+
stop_time = nil
|
61
|
+
stop_time_iso8601 = nil
|
62
|
+
if !timeout_milliseconds.nil?
|
63
|
+
stop_time = clock.now + (timeout_milliseconds.to_f / 1000.0)
|
64
|
+
stop_time_iso8601 = clock.iso8601(stop_time, precision: 5)
|
65
|
+
end
|
66
|
+
|
67
|
+
logger.trace { "Cycling (Interval Milliseconds: #{interval_milliseconds}, Timeout Milliseconds: #{timeout_milliseconds.inspect}, Stop Time: #{stop_time_iso8601})" }
|
68
|
+
|
69
|
+
cycle = -1
|
70
|
+
result = nil
|
71
|
+
loop do
|
72
|
+
cycle += 1
|
73
|
+
telemetry.record :cycle, cycle
|
74
|
+
|
75
|
+
result, elapsed_milliseconds = invoke(cycle, &action)
|
76
|
+
|
77
|
+
if delay_condition.(result)
|
78
|
+
logger.debug { "Got no results from action (Cycle: #{cycle})" }
|
79
|
+
delay(elapsed_milliseconds)
|
80
|
+
else
|
81
|
+
logger.debug { "Got results from action (Cycle: #{cycle})" }
|
82
|
+
telemetry.record :got_result
|
83
|
+
break
|
84
|
+
end
|
85
|
+
|
86
|
+
if !timeout_milliseconds.nil?
|
87
|
+
now = clock.now
|
88
|
+
if now >= stop_time
|
89
|
+
logger.debug { "Timeout has lapsed (Cycle: #{cycle}, Stop Time: #{stop_time_iso8601}, Timeout Milliseconds: #{timeout_milliseconds})" }
|
90
|
+
telemetry.record :timed_out, now
|
91
|
+
break
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
logger.debug { "Cycled (Iterations: #{cycle + 1}, Interval Milliseconds: #{interval_milliseconds}, Timeout Milliseconds: #{timeout_milliseconds.inspect}, Stop Time: #{stop_time_iso8601})" }
|
97
|
+
|
98
|
+
return result
|
99
|
+
end
|
100
|
+
|
101
|
+
def invoke(cycle, &action)
|
102
|
+
if action.nil?
|
103
|
+
raise Error, "Poll must be actuated with a block"
|
104
|
+
end
|
105
|
+
|
106
|
+
action_start_time = clock.now
|
107
|
+
|
108
|
+
logger.trace { "Invoking action (Cycle: #{cycle}, Start Time: #{clock.iso8601(action_start_time, precision: 5)})" }
|
109
|
+
|
110
|
+
result = action.call(cycle)
|
111
|
+
|
112
|
+
action_end_time = clock.now
|
113
|
+
elapsed_milliseconds = clock.elapsed_milliseconds(action_start_time, action_end_time)
|
114
|
+
|
115
|
+
telemetry.record :invoked_action, elapsed_milliseconds
|
116
|
+
|
117
|
+
logger.debug { "Invoked action (Cycle: #{cycle}, Elapsed Milliseconds: #{elapsed_milliseconds}, Start Time: #{clock.iso8601(action_start_time, precision: 5)}, End Time: #{clock.iso8601(action_end_time, precision: 5)})" }
|
118
|
+
|
119
|
+
[result, elapsed_milliseconds]
|
120
|
+
end
|
121
|
+
|
122
|
+
def delay(elapsed_milliseconds)
|
123
|
+
delay_milliseconds = interval_milliseconds - elapsed_milliseconds
|
124
|
+
|
125
|
+
logger.trace { "Delaying (Delay Milliseconds: #{delay_milliseconds}, Interval Milliseconds: #{interval_milliseconds}, Elapsed Milliseconds: #{elapsed_milliseconds})" }
|
126
|
+
|
127
|
+
if delay_milliseconds <= 0
|
128
|
+
logger.debug { "Elapsed time exceeds or equals interval. Not delayed. (Delay Milliseconds: #{delay_milliseconds}, Interval Milliseconds: #{interval_milliseconds}, Elapsed Milliseconds: #{elapsed_milliseconds})" }
|
129
|
+
return
|
130
|
+
end
|
131
|
+
|
132
|
+
delay_seconds = (delay_milliseconds.to_f / 1000.0)
|
133
|
+
|
134
|
+
sleep delay_seconds
|
135
|
+
|
136
|
+
telemetry.record :delayed, delay_milliseconds
|
137
|
+
|
138
|
+
logger.debug { "Finished delaying (Delay Milliseconds: #{delay_milliseconds}, Interval Milliseconds: #{interval_milliseconds}, Elapsed Milliseconds: #{elapsed_milliseconds})" }
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.register_telemetry_sink(cycle)
|
142
|
+
sink = Telemetry.sink
|
143
|
+
cycle.telemetry.register(sink)
|
144
|
+
sink
|
145
|
+
end
|
146
|
+
|
147
|
+
module Telemetry
|
148
|
+
class Sink
|
149
|
+
include ::Telemetry::Sink
|
150
|
+
|
151
|
+
record :cycle
|
152
|
+
record :invoked_action
|
153
|
+
record :got_result
|
154
|
+
record :delayed
|
155
|
+
record :timed_out
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.sink
|
159
|
+
Sink.new
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
module Substitute
|
164
|
+
def self.build
|
165
|
+
instance = Poll.build(timeout_milliseconds: 0)
|
166
|
+
|
167
|
+
sink = Poll.register_telemetry_sink(instance)
|
168
|
+
instance.telemetry_sink = sink
|
169
|
+
|
170
|
+
instance.configure
|
171
|
+
|
172
|
+
instance
|
173
|
+
end
|
174
|
+
|
175
|
+
class Poll < ::Poll
|
176
|
+
attr_accessor :telemetry_sink
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
data/lib/poll/log.rb
ADDED
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evt-poll
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- The Eventide Project
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-08-07 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/poll.rb
|
76
|
+
- lib/poll/controls.rb
|
77
|
+
- lib/poll/controls/time.rb
|
78
|
+
- lib/poll/cycle.rb
|
79
|
+
- lib/poll/defaults.rb
|
80
|
+
- lib/poll/log.rb
|
81
|
+
homepage: https://github.com/eventide-project/cycle
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '2.4'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.7.3
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Generalized implementation of polling
|
105
|
+
test_files: []
|