Skip to content

Commit fc751ab

Browse files
committed
add correct module nesting for moved files
1 parent f88e6ec commit fc751ab

File tree

8 files changed

+519
-489
lines changed

8 files changed

+519
-489
lines changed
Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,48 @@
11
require "concurrent/map"
22

33
module LaunchDarkly
4-
#
5-
# A thread-safe in-memory store that uses the same semantics that Faraday would expect, although we
6-
# no longer use Faraday. This is used by Requestor, when we are not in a Rails environment.
7-
#
8-
# @api private
9-
#
10-
class ThreadSafeMemoryStore
4+
module Impl
115
#
12-
# Default constructor
6+
# A thread-safe in-memory store that uses the same semantics that Faraday would expect, although we
7+
# no longer use Faraday. This is used by Requestor, when we are not in a Rails environment.
138
#
14-
# @return [ThreadSafeMemoryStore] a new store
15-
def initialize
16-
@cache = Concurrent::Map.new
17-
end
18-
19-
#
20-
# Read a value from the cache
21-
# @param key [Object] the cache key
9+
# @api private
2210
#
23-
# @return [Object] the cache value
24-
def read(key)
25-
@cache[key]
26-
end
11+
class ThreadSafeMemoryStore
12+
#
13+
# Default constructor
14+
#
15+
# @return [ThreadSafeMemoryStore] a new store
16+
def initialize
17+
@cache = Concurrent::Map.new
18+
end
2719

28-
#
29-
# Store a value in the cache
30-
# @param key [Object] the cache key
31-
# @param value [Object] the value to associate with the key
32-
#
33-
# @return [Object] the value
34-
def write(key, value)
35-
@cache[key] = value
36-
end
20+
#
21+
# Read a value from the cache
22+
# @param key [Object] the cache key
23+
#
24+
# @return [Object] the cache value
25+
def read(key)
26+
@cache[key]
27+
end
3728

38-
#
39-
# Delete a value in the cache
40-
# @param key [Object] the cache key
41-
def delete(key)
42-
@cache.delete(key)
29+
#
30+
# Store a value in the cache
31+
# @param key [Object] the cache key
32+
# @param value [Object] the value to associate with the key
33+
#
34+
# @return [Object] the value
35+
def write(key, value)
36+
@cache[key] = value
37+
end
38+
39+
#
40+
# Delete a value in the cache
41+
# @param key [Object] the cache key
42+
def delete(key)
43+
@cache.delete(key)
44+
end
4345
end
4446
end
4547
end
48+

lib/ldclient-rb/impl/data_source/polling.rb

Lines changed: 88 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -5,98 +5,103 @@
55
require "thread"
66

77
module LaunchDarkly
8-
# @api private
9-
class PollingProcessor
10-
def initialize(config, requestor)
11-
@config = config
12-
@requestor = requestor
13-
@initialized = Concurrent::AtomicBoolean.new(false)
14-
@started = Concurrent::AtomicBoolean.new(false)
15-
@ready = Concurrent::Event.new
16-
@task = Impl::RepeatingTask.new(@config.poll_interval, 0, -> { self.poll }, @config.logger, 'LD/PollingDataSource')
17-
end
8+
module Impl
9+
module DataSource
10+
# @api private
11+
class PollingProcessor
12+
def initialize(config, requestor)
13+
@config = config
14+
@requestor = requestor
15+
@initialized = Concurrent::AtomicBoolean.new(false)
16+
@started = Concurrent::AtomicBoolean.new(false)
17+
@ready = Concurrent::Event.new
18+
@task = Impl::RepeatingTask.new(@config.poll_interval, 0, -> { self.poll }, @config.logger, 'LD/PollingDataSource')
19+
end
1820

19-
def initialized?
20-
@initialized.value
21-
end
21+
def initialized?
22+
@initialized.value
23+
end
2224

23-
def start
24-
return @ready unless @started.make_true
25-
@config.logger.info { "[LDClient] Initializing polling connection" }
26-
@task.start
27-
@ready
28-
end
25+
def start
26+
return @ready unless @started.make_true
27+
@config.logger.info { "[LDClient] Initializing polling connection" }
28+
@task.start
29+
@ready
30+
end
2931

30-
def stop
31-
stop_with_error_info
32-
end
32+
def stop
33+
stop_with_error_info
34+
end
3335

34-
def poll
35-
begin
36-
all_data = @requestor.request_all_data
37-
if all_data
38-
update_sink_or_data_store.init(all_data)
39-
if @initialized.make_true
40-
@config.logger.info { "[LDClient] Polling connection initialized" }
41-
@ready.set
36+
def poll
37+
begin
38+
all_data = @requestor.request_all_data
39+
if all_data
40+
update_sink_or_data_store.init(all_data)
41+
if @initialized.make_true
42+
@config.logger.info { "[LDClient] Polling connection initialized" }
43+
@ready.set
44+
end
45+
end
46+
@config.data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::VALID, nil)
47+
rescue JSON::ParserError => e
48+
@config.logger.error { "[LDClient] JSON parsing failed for polling response." }
49+
error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
50+
LaunchDarkly::Interfaces::DataSource::ErrorInfo::INVALID_DATA,
51+
0,
52+
e.to_s,
53+
Time.now
54+
)
55+
@config.data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED, error_info)
56+
rescue Impl::DataSource::UnexpectedResponseError => e
57+
error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
58+
LaunchDarkly::Interfaces::DataSource::ErrorInfo::ERROR_RESPONSE, e.status, nil, Time.now)
59+
message = Util.http_error_message(e.status, "polling request", "will retry")
60+
@config.logger.error { "[LDClient] #{message}" }
61+
62+
if Util.http_error_recoverable?(e.status)
63+
@config.data_source_update_sink&.update_status(
64+
LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
65+
error_info
66+
)
67+
else
68+
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
69+
stop_with_error_info error_info
70+
end
71+
rescue StandardError => e
72+
Util.log_exception(@config.logger, "Exception while polling", e)
73+
@config.data_source_update_sink&.update_status(
74+
LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
75+
LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(LaunchDarkly::Interfaces::DataSource::ErrorInfo::UNKNOWN, 0, e.to_s, Time.now)
76+
)
4277
end
4378
end
44-
@config.data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::VALID, nil)
45-
rescue JSON::ParserError => e
46-
@config.logger.error { "[LDClient] JSON parsing failed for polling response." }
47-
error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
48-
LaunchDarkly::Interfaces::DataSource::ErrorInfo::INVALID_DATA,
49-
0,
50-
e.to_s,
51-
Time.now
52-
)
53-
@config.data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED, error_info)
54-
rescue UnexpectedResponseError => e
55-
error_info = LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(
56-
LaunchDarkly::Interfaces::DataSource::ErrorInfo::ERROR_RESPONSE, e.status, nil, Time.now)
57-
message = Util.http_error_message(e.status, "polling request", "will retry")
58-
@config.logger.error { "[LDClient] #{message}" }
5979

60-
if Util.http_error_recoverable?(e.status)
61-
@config.data_source_update_sink&.update_status(
62-
LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
63-
error_info
64-
)
65-
else
66-
@ready.set # if client was waiting on us, make it stop waiting - has no effect if already set
67-
stop_with_error_info error_info
80+
#
81+
# The original implementation of this class relied on the feature store
82+
# directly, which we are trying to move away from. Customers who might have
83+
# instantiated this directly for some reason wouldn't know they have to set
84+
# the config's sink manually, so we have to fall back to the store if the
85+
# sink isn't present.
86+
#
87+
# The next major release should be able to simplify this structure and
88+
# remove the need for fall back to the data store because the update sink
89+
# should always be present.
90+
#
91+
private def update_sink_or_data_store
92+
@config.data_source_update_sink || @config.feature_store
6893
end
69-
rescue StandardError => e
70-
Util.log_exception(@config.logger, "Exception while polling", e)
71-
@config.data_source_update_sink&.update_status(
72-
LaunchDarkly::Interfaces::DataSource::Status::INTERRUPTED,
73-
LaunchDarkly::Interfaces::DataSource::ErrorInfo.new(LaunchDarkly::Interfaces::DataSource::ErrorInfo::UNKNOWN, 0, e.to_s, Time.now)
74-
)
75-
end
76-
end
77-
78-
#
79-
# The original implementation of this class relied on the feature store
80-
# directly, which we are trying to move away from. Customers who might have
81-
# instantiated this directly for some reason wouldn't know they have to set
82-
# the config's sink manually, so we have to fall back to the store if the
83-
# sink isn't present.
84-
#
85-
# The next major release should be able to simplify this structure and
86-
# remove the need for fall back to the data store because the update sink
87-
# should always be present.
88-
#
89-
private def update_sink_or_data_store
90-
@config.data_source_update_sink || @config.feature_store
91-
end
9294

93-
#
94-
# @param [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] error_info
95-
#
96-
private def stop_with_error_info(error_info = nil)
97-
@task.stop
98-
@config.logger.info { "[LDClient] Polling connection stopped" }
99-
@config.data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::OFF, error_info)
95+
#
96+
# @param [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] error_info
97+
#
98+
private def stop_with_error_info(error_info = nil)
99+
@task.stop
100+
@config.logger.info { "[LDClient] Polling connection stopped" }
101+
@config.data_source_update_sink&.update_status(LaunchDarkly::Interfaces::DataSource::Status::OFF, error_info)
102+
end
103+
end
100104
end
101105
end
102106
end
107+

0 commit comments

Comments
 (0)