ff-ruby-server-sdk 0.0.2 → 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 +4 -4
- data/.run/build.sh.run.xml +17 -0
- data/.run/install.sh.run.xml +17 -0
- data/.run/openapi.sh.run.xml +17 -0
- data/.run/publish.sh.run.xml +17 -0
- data/.run/sdk_test.rb.run.xml +3 -3
- data/.run/unpublish.sh.run.xml +17 -0
- data/CHANGELOG.md +1 -1
- data/Gemfile +20 -3
- data/README.md +155 -7
- data/api.yaml +736 -0
- data/example/example.rb +99 -3
- data/lib/ff/ruby/server/sdk/api/auth_service.rb +91 -0
- data/lib/ff/ruby/server/sdk/api/cf_client.rb +93 -0
- data/lib/ff/ruby/server/sdk/api/client_callback.rb +45 -0
- data/lib/ff/ruby/server/sdk/api/config.rb +140 -0
- data/lib/ff/ruby/server/sdk/api/config_builder.rb +116 -0
- data/lib/ff/ruby/server/sdk/api/default_cache.rb +112 -0
- data/lib/ff/ruby/server/sdk/api/evaluation.rb +29 -0
- data/lib/ff/ruby/server/sdk/api/evaluator.rb +526 -0
- data/lib/ff/ruby/server/sdk/api/file_map_store.rb +60 -0
- data/lib/ff/ruby/server/sdk/api/flag_evaluate_callback.rb +13 -0
- data/lib/ff/ruby/server/sdk/api/inner_client.rb +311 -0
- data/lib/ff/ruby/server/sdk/api/inner_client_flag_evaluate_callback.rb +30 -0
- data/lib/ff/ruby/server/sdk/api/inner_client_metrics_callback.rb +33 -0
- data/lib/ff/ruby/server/sdk/api/inner_client_repository_callback.rb +44 -0
- data/lib/ff/ruby/server/sdk/api/inner_client_updater.rb +63 -0
- data/lib/ff/ruby/server/sdk/api/metrics_callback.rb +19 -0
- data/lib/ff/ruby/server/sdk/api/metrics_event.rb +16 -0
- data/lib/ff/ruby/server/sdk/api/metrics_processor.rb +297 -0
- data/lib/ff/ruby/server/sdk/api/operators.rb +20 -0
- data/lib/ff/ruby/server/sdk/api/polling_processor.rb +164 -0
- data/lib/ff/ruby/server/sdk/api/repository_callback.rb +28 -0
- data/lib/ff/ruby/server/sdk/api/storage_repository.rb +263 -0
- data/lib/ff/ruby/server/sdk/api/summary_metrics.rb +16 -0
- data/lib/ff/ruby/server/sdk/api/update_processor.rb +149 -0
- data/lib/ff/ruby/server/sdk/common/cache.rb +27 -0
- data/lib/ff/ruby/server/sdk/common/closeable.rb +7 -0
- data/lib/ff/ruby/server/sdk/common/destroyable.rb +12 -0
- data/lib/ff/ruby/server/sdk/common/repository.rb +45 -0
- data/lib/ff/ruby/server/sdk/common/storage.rb +29 -0
- data/lib/ff/ruby/server/sdk/connector/connector.rb +44 -0
- data/lib/ff/ruby/server/sdk/connector/events.rb +118 -0
- data/lib/ff/ruby/server/sdk/connector/harness_connector.rb +236 -0
- data/lib/ff/ruby/server/sdk/connector/service.rb +19 -0
- data/lib/ff/ruby/server/sdk/connector/updater.rb +32 -0
- data/lib/ff/ruby/server/sdk/dto/message.rb +13 -0
- data/lib/ff/ruby/server/sdk/dto/target.rb +24 -0
- data/lib/ff/ruby/server/sdk/version.rb +2 -1
- data/lib/ff/ruby/server/sdk.rb +39 -3
- data/openapitools.json +7 -0
- data/scripts/openapi.sh +35 -0
- data/scripts/sdk_specs.sh +1 -1
- metadata +46 -3
- data/lib/ff/ruby/server/sdk/cf_client.rb +0 -6
@@ -0,0 +1,263 @@
|
|
1
|
+
require_relative "operators"
|
2
|
+
require_relative "repository_callback"
|
3
|
+
require_relative "../common/repository"
|
4
|
+
|
5
|
+
class StorageRepository < Repository
|
6
|
+
|
7
|
+
def initialize(cache, callback = nil, store = nil, logger = nil)
|
8
|
+
|
9
|
+
@cache = cache
|
10
|
+
@store = store
|
11
|
+
@callback = callback
|
12
|
+
|
13
|
+
if logger != nil
|
14
|
+
|
15
|
+
@logger = logger
|
16
|
+
else
|
17
|
+
|
18
|
+
@logger = Logger.new(STDOUT)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_flag(identifier, cacheable = true)
|
23
|
+
|
24
|
+
flag_key = format_flag_key(identifier)
|
25
|
+
flag = @cache.get(flag_key)
|
26
|
+
|
27
|
+
if flag != nil
|
28
|
+
|
29
|
+
return flag
|
30
|
+
end
|
31
|
+
|
32
|
+
if @store != nil
|
33
|
+
|
34
|
+
flag = @store.get(flag_key)
|
35
|
+
if flag != nil && cacheable
|
36
|
+
|
37
|
+
@cache.set(flag_key, flag)
|
38
|
+
end
|
39
|
+
|
40
|
+
return flag
|
41
|
+
end
|
42
|
+
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_segment(identifier, cacheable = true)
|
47
|
+
|
48
|
+
segment_key = format_segment_key(identifier)
|
49
|
+
segment = @cache.get(segment_key)
|
50
|
+
|
51
|
+
if segment != nil
|
52
|
+
|
53
|
+
return segment
|
54
|
+
end
|
55
|
+
|
56
|
+
if @store != nil
|
57
|
+
|
58
|
+
segment = @store.get(segment_key)
|
59
|
+
if segment != nil && cacheable
|
60
|
+
|
61
|
+
@cache.set(segment_key, segment)
|
62
|
+
end
|
63
|
+
|
64
|
+
return segment
|
65
|
+
end
|
66
|
+
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def find_flags_by_segment(identifier)
|
71
|
+
|
72
|
+
result = []
|
73
|
+
keys = @cache.keys
|
74
|
+
|
75
|
+
if @store != nil
|
76
|
+
|
77
|
+
keys = @store.keys
|
78
|
+
end
|
79
|
+
|
80
|
+
keys.each do |key|
|
81
|
+
|
82
|
+
flag = get_flag(key)
|
83
|
+
|
84
|
+
if flag != nil && !flag.rules.length > 0
|
85
|
+
|
86
|
+
flag.rules.each do |rule|
|
87
|
+
|
88
|
+
rule.clauses.each do |clause|
|
89
|
+
|
90
|
+
if clause.op == Operators.SEGMENT_MATCH && clause.values.include(identifier)
|
91
|
+
|
92
|
+
result.push(flag.feature)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
result
|
100
|
+
end
|
101
|
+
|
102
|
+
def set_flag(identifier, feature_config)
|
103
|
+
|
104
|
+
if is_flag_outdated(identifier, feature_config)
|
105
|
+
|
106
|
+
@logger.debug "Flag " + identifier + " already exists"
|
107
|
+
return
|
108
|
+
end
|
109
|
+
|
110
|
+
flag_key = format_flag_key(identifier)
|
111
|
+
|
112
|
+
if @store != nil
|
113
|
+
|
114
|
+
@store.set(flag_key, feature_config)
|
115
|
+
@cache.delete(flag_key)
|
116
|
+
|
117
|
+
@logger.debug "Flag " + identifier + " successfully stored and cache invalidated"
|
118
|
+
else
|
119
|
+
|
120
|
+
@cache.set(flag_key, feature_config)
|
121
|
+
|
122
|
+
@logger.debug "Flag " + identifier + " successfully cached"
|
123
|
+
end
|
124
|
+
|
125
|
+
if @callback != nil
|
126
|
+
|
127
|
+
unless @callback.kind_of?(RepositoryCallback)
|
128
|
+
|
129
|
+
raise "The 'callback' parameter must be of '" + RepositoryCallback.to_s + "' data type"
|
130
|
+
end
|
131
|
+
|
132
|
+
@callback.on_flag_stored(identifier)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def set_segment(identifier, segment)
|
137
|
+
|
138
|
+
if is_segment_outdated(identifier, segment)
|
139
|
+
|
140
|
+
@logger.debug "Segment " + identifier + " already exists"
|
141
|
+
return
|
142
|
+
end
|
143
|
+
|
144
|
+
segment_key = format_segment_key(identifier)
|
145
|
+
|
146
|
+
if @store != nil
|
147
|
+
|
148
|
+
@store.set(segment_key, segment)
|
149
|
+
@cache.delete(segment_key)
|
150
|
+
|
151
|
+
@logger.debug "Segment " + identifier + " successfully stored and cache invalidated"
|
152
|
+
else
|
153
|
+
|
154
|
+
@cache.set(segment_key, segment)
|
155
|
+
|
156
|
+
@logger.debug "Segment " + identifier + " successfully cached"
|
157
|
+
end
|
158
|
+
|
159
|
+
if @callback != nil
|
160
|
+
|
161
|
+
unless @callback.kind_of?(RepositoryCallback)
|
162
|
+
|
163
|
+
raise "The 'callback' parameter must be of '" + RepositoryCallback.to_s + "' data type"
|
164
|
+
end
|
165
|
+
|
166
|
+
@callback.on_segment_stored(identifier)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def delete_flag(identifier)
|
171
|
+
|
172
|
+
flag_key = format_flag_key(identifier)
|
173
|
+
|
174
|
+
if @store != nil
|
175
|
+
|
176
|
+
@store.delete(flag_key)
|
177
|
+
|
178
|
+
@logger.debug "Flag " + identifier + " successfully deleted from store"
|
179
|
+
end
|
180
|
+
|
181
|
+
@cache.delete(flag_key)
|
182
|
+
|
183
|
+
@logger.debug "Flag " + identifier + " successfully deleted from cache"
|
184
|
+
|
185
|
+
if @callback != nil
|
186
|
+
|
187
|
+
unless @callback.kind_of?(RepositoryCallback)
|
188
|
+
|
189
|
+
raise "The 'callback' parameter must be of '" + RepositoryCallback.to_s + "' data type"
|
190
|
+
end
|
191
|
+
|
192
|
+
@callback.on_flag_deleted(identifier)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def delete_segment(identifier)
|
197
|
+
|
198
|
+
segment_key = format_segment_key(identifier)
|
199
|
+
|
200
|
+
if @store != nil
|
201
|
+
|
202
|
+
@store.delete(segment_key)
|
203
|
+
|
204
|
+
@logger.debug "Segment " + identifier + " successfully deleted from store"
|
205
|
+
end
|
206
|
+
|
207
|
+
@cache.delete(segment_key)
|
208
|
+
|
209
|
+
@logger.debug "Segment " + identifier + " successfully deleted from cache"
|
210
|
+
|
211
|
+
if @callback != nil
|
212
|
+
|
213
|
+
unless @callback.kind_of?(RepositoryCallback)
|
214
|
+
|
215
|
+
raise "The 'callback' parameter must be of '" + RepositoryCallback.to_s + "' data type"
|
216
|
+
end
|
217
|
+
|
218
|
+
@callback.on_segment_deleted(identifier)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def close
|
223
|
+
|
224
|
+
if @store != nil
|
225
|
+
|
226
|
+
@store.close
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
protected
|
231
|
+
|
232
|
+
def is_flag_outdated(identifier, new_feature_config)
|
233
|
+
|
234
|
+
flag = get_flag(identifier, false)
|
235
|
+
if flag != nil && flag.version != new_feature_config.version
|
236
|
+
|
237
|
+
return flag.version >= new_feature_config.version
|
238
|
+
end
|
239
|
+
|
240
|
+
false
|
241
|
+
end
|
242
|
+
|
243
|
+
def is_segment_outdated(identifier, new_segment)
|
244
|
+
|
245
|
+
segment = get_segment(identifier, false)
|
246
|
+
if segment != nil && segment.version != new_segment.version
|
247
|
+
|
248
|
+
return segment.version >= new_segment.version
|
249
|
+
end
|
250
|
+
|
251
|
+
false
|
252
|
+
end
|
253
|
+
|
254
|
+
def format_flag_key(identifier)
|
255
|
+
|
256
|
+
"flags_" + identifier
|
257
|
+
end
|
258
|
+
|
259
|
+
def format_segment_key(identifier)
|
260
|
+
|
261
|
+
"segments_" + identifier
|
262
|
+
end
|
263
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class SummaryMetrics
|
2
|
+
|
3
|
+
attr_accessor :feature_name, :variation_identifier, :variation_value
|
4
|
+
|
5
|
+
def initialize(
|
6
|
+
|
7
|
+
feature_name,
|
8
|
+
variation_identifier,
|
9
|
+
variation_value
|
10
|
+
)
|
11
|
+
|
12
|
+
@feature_name = feature_name
|
13
|
+
@variation_value = variation_value
|
14
|
+
@variation_identifier = variation_identifier
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require "concurrent-ruby"
|
2
|
+
|
3
|
+
require_relative "../common/closeable"
|
4
|
+
|
5
|
+
class UpdateProcessor < Closeable
|
6
|
+
|
7
|
+
def initialize(
|
8
|
+
|
9
|
+
connector,
|
10
|
+
repository,
|
11
|
+
callback,
|
12
|
+
logger
|
13
|
+
)
|
14
|
+
|
15
|
+
@connector = connector
|
16
|
+
@repository = repository
|
17
|
+
@updater = callback
|
18
|
+
@executor = Concurrent::FixedThreadPool.new(100)
|
19
|
+
|
20
|
+
if logger != nil
|
21
|
+
|
22
|
+
@logger = logger
|
23
|
+
else
|
24
|
+
|
25
|
+
@logger = Logger.new(STDOUT)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def start
|
30
|
+
|
31
|
+
@logger.info "Starting updater (EventSource)"
|
32
|
+
|
33
|
+
if @updater != nil
|
34
|
+
|
35
|
+
unless @updater.kind_of?(Updater)
|
36
|
+
|
37
|
+
raise "The 'callback' parameter must be of '" + Updater.to_s + "' data type"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
if @connector != nil
|
42
|
+
|
43
|
+
unless @connector.kind_of?(Connector)
|
44
|
+
|
45
|
+
raise "The 'connector' must be of '" + Connector.to_s + "' data type"
|
46
|
+
end
|
47
|
+
|
48
|
+
@executor.post do
|
49
|
+
|
50
|
+
@stream = @connector.stream(@updater)
|
51
|
+
@stream.start
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def stop
|
57
|
+
|
58
|
+
@logger.info "Stopping updater (EventSource)"
|
59
|
+
|
60
|
+
if @stream != nil
|
61
|
+
|
62
|
+
@stream.stop
|
63
|
+
end
|
64
|
+
|
65
|
+
@executor.shutdown
|
66
|
+
@executor.wait_for_termination(3)
|
67
|
+
|
68
|
+
if @executor.shuttingdown?
|
69
|
+
|
70
|
+
@executor.kill
|
71
|
+
end
|
72
|
+
|
73
|
+
@logger.info "Updater stopped (EventSource)"
|
74
|
+
end
|
75
|
+
|
76
|
+
def close
|
77
|
+
|
78
|
+
@logger.info "Closing UpdateProcessor"
|
79
|
+
|
80
|
+
stop
|
81
|
+
end
|
82
|
+
|
83
|
+
def update(message)
|
84
|
+
|
85
|
+
if message["domain"] == "flag"
|
86
|
+
|
87
|
+
@executor.post do
|
88
|
+
|
89
|
+
process_flag(message)
|
90
|
+
end
|
91
|
+
|
92
|
+
return
|
93
|
+
end
|
94
|
+
|
95
|
+
if message["domain"] == "target-segment"
|
96
|
+
|
97
|
+
@executor.post do
|
98
|
+
|
99
|
+
process_segment(message)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
protected
|
105
|
+
|
106
|
+
def process_flag(message)
|
107
|
+
|
108
|
+
@logger.info "Processing flag message: " + message.to_s
|
109
|
+
|
110
|
+
config = @connector.get_flag(message["identifier"])
|
111
|
+
|
112
|
+
if config != nil
|
113
|
+
|
114
|
+
if message["event"] == "create" || message["event"] == "patch"
|
115
|
+
|
116
|
+
@repository.set_flag(message["identifier"], config)
|
117
|
+
|
118
|
+
else
|
119
|
+
|
120
|
+
if message["event"] == "delete"
|
121
|
+
|
122
|
+
@repository.delete_flag(message["identifier"])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def process_segment(message)
|
129
|
+
|
130
|
+
@logger.info "Processing segment message: " + message.to_s
|
131
|
+
|
132
|
+
segment = @connector.get_segment(message["identifier"])
|
133
|
+
|
134
|
+
if segment != nil
|
135
|
+
|
136
|
+
if message["event"] == "create" || message["event"] == "patch"
|
137
|
+
|
138
|
+
@repository.set_segment(message.identifier, segment)
|
139
|
+
|
140
|
+
else
|
141
|
+
|
142
|
+
if message["event"] == "delete"
|
143
|
+
|
144
|
+
@repository.delete_segment(message["identifier"])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Cache
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
|
5
|
+
@tbi = "To be implemented"
|
6
|
+
end
|
7
|
+
|
8
|
+
def set(key, value)
|
9
|
+
|
10
|
+
raise @tbi
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(key)
|
14
|
+
|
15
|
+
raise @tbi
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete(key)
|
19
|
+
|
20
|
+
raise @tbi
|
21
|
+
end
|
22
|
+
|
23
|
+
def keys
|
24
|
+
|
25
|
+
raise @tbi
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "closeable"
|
2
|
+
|
3
|
+
class Repository < Closeable
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
|
8
|
+
@tbi = "To be implemented"
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_flag(identifier, cacheable = true)
|
12
|
+
|
13
|
+
raise @tbi
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_segment(identifier, cacheable = true)
|
17
|
+
|
18
|
+
raise @tbi
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_flags_by_segment(identifier)
|
22
|
+
|
23
|
+
raise @tbi
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_flag(identifier, feature_config)
|
27
|
+
|
28
|
+
raise @tbi
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_segment(identifier, segment)
|
32
|
+
|
33
|
+
raise @tbi
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_flag(identifier)
|
37
|
+
|
38
|
+
raise @tbi
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete_segment(identifier)
|
42
|
+
|
43
|
+
raise @tbi
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative "closeable"
|
2
|
+
|
3
|
+
class Storage < Closeable
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
|
7
|
+
@tbi = "To be implemented"
|
8
|
+
end
|
9
|
+
|
10
|
+
def set(key, value)
|
11
|
+
|
12
|
+
raise @tbi
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(key)
|
16
|
+
|
17
|
+
raise @tbi
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete(key)
|
21
|
+
|
22
|
+
raise @tbi
|
23
|
+
end
|
24
|
+
|
25
|
+
def keys
|
26
|
+
|
27
|
+
raise @tbi
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative '../common/closeable'
|
2
|
+
|
3
|
+
class Connector < Closeable
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
|
7
|
+
@tbi = "To be implemented"
|
8
|
+
end
|
9
|
+
|
10
|
+
def authenticate
|
11
|
+
|
12
|
+
raise @tbi
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_flags
|
16
|
+
|
17
|
+
raise @tbi
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_flag(identifier)
|
21
|
+
|
22
|
+
raise @tbi
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_segments
|
26
|
+
|
27
|
+
raise @tbi
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_segment(identifier)
|
31
|
+
|
32
|
+
raise @tbi
|
33
|
+
end
|
34
|
+
|
35
|
+
def post_metrics(metrics)
|
36
|
+
|
37
|
+
raise @tbi
|
38
|
+
end
|
39
|
+
|
40
|
+
def stream(updater)
|
41
|
+
|
42
|
+
raise @tbi
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require "json"
|
2
|
+
require "sse-client"
|
3
|
+
|
4
|
+
require_relative './service'
|
5
|
+
|
6
|
+
class Events < Service
|
7
|
+
|
8
|
+
def initialize(
|
9
|
+
|
10
|
+
url,
|
11
|
+
headers,
|
12
|
+
updater,
|
13
|
+
logger = nil
|
14
|
+
)
|
15
|
+
|
16
|
+
if @updater != nil
|
17
|
+
|
18
|
+
unless @updater.kind_of?(Updater)
|
19
|
+
|
20
|
+
raise "The 'callback' parameter must be of '" + Updater.to_s + "' data type"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@updater = updater
|
25
|
+
|
26
|
+
if logger != nil
|
27
|
+
|
28
|
+
@logger = logger
|
29
|
+
else
|
30
|
+
|
31
|
+
@logger = Logger.new(STDOUT)
|
32
|
+
end
|
33
|
+
|
34
|
+
@sse = SSE::EventSource.new(
|
35
|
+
|
36
|
+
url = url,
|
37
|
+
query = {},
|
38
|
+
headers = headers
|
39
|
+
)
|
40
|
+
|
41
|
+
@sse.open do
|
42
|
+
|
43
|
+
on_open
|
44
|
+
end
|
45
|
+
|
46
|
+
@sse.error do |error|
|
47
|
+
|
48
|
+
if error != nil
|
49
|
+
|
50
|
+
@logger.error "SSE ERROR: " + error.body
|
51
|
+
end
|
52
|
+
|
53
|
+
on_error
|
54
|
+
end
|
55
|
+
|
56
|
+
@sse.message do |message|
|
57
|
+
|
58
|
+
on_message(message)
|
59
|
+
end
|
60
|
+
|
61
|
+
@sse.on("*") do |message|
|
62
|
+
|
63
|
+
on_message(message)
|
64
|
+
end
|
65
|
+
|
66
|
+
@updater.on_ready
|
67
|
+
end
|
68
|
+
|
69
|
+
def start
|
70
|
+
|
71
|
+
@logger.info "Starting EventSource service"
|
72
|
+
|
73
|
+
@sse.start
|
74
|
+
end
|
75
|
+
|
76
|
+
def stop
|
77
|
+
|
78
|
+
@logger.info "Stopping EventSource service"
|
79
|
+
|
80
|
+
on_closed
|
81
|
+
end
|
82
|
+
|
83
|
+
def close
|
84
|
+
|
85
|
+
stop
|
86
|
+
end
|
87
|
+
|
88
|
+
def on_open
|
89
|
+
|
90
|
+
@logger.info "EventSource connected"
|
91
|
+
|
92
|
+
@updater.on_connected
|
93
|
+
end
|
94
|
+
|
95
|
+
def on_error
|
96
|
+
|
97
|
+
@logger.error "EventSource error"
|
98
|
+
|
99
|
+
@updater.on_error
|
100
|
+
|
101
|
+
stop
|
102
|
+
end
|
103
|
+
|
104
|
+
def on_closed
|
105
|
+
|
106
|
+
@logger.info "EventSource disconnected"
|
107
|
+
|
108
|
+
@updater.on_disconnected
|
109
|
+
end
|
110
|
+
|
111
|
+
def on_message(message)
|
112
|
+
|
113
|
+
@logger.debug "EventSource message received " + message.to_s
|
114
|
+
|
115
|
+
msg = JSON.parse(message)
|
116
|
+
@updater.update(msg)
|
117
|
+
end
|
118
|
+
end
|