diff --git a/launchdarkly-server-sdk.gemspec b/launchdarkly-server-sdk.gemspec index 2a5dc609..b6ccb78a 100644 --- a/launchdarkly-server-sdk.gemspec +++ b/launchdarkly-server-sdk.gemspec @@ -37,7 +37,7 @@ Gem::Specification.new do |spec| spec.add_runtime_dependency "semantic", "~> 1.6" spec.add_runtime_dependency "concurrent-ruby", "~> 1.1" - spec.add_runtime_dependency "ld-eventsource", "2.2.2" + spec.add_runtime_dependency "ld-eventsource", "2.2.3" spec.add_runtime_dependency "observer", "~> 0.1.2" spec.add_runtime_dependency "zlib", "~> 3.1" unless RUBY_PLATFORM == "java" # Please keep ld-eventsource dependency as an exact version so that bugfixes to diff --git a/lib/ldclient-rb/events.rb b/lib/ldclient-rb/events.rb index bb787fbe..3418b2e1 100644 --- a/lib/ldclient-rb/events.rb +++ b/lib/ldclient-rb/events.rb @@ -243,17 +243,17 @@ def initialize(inbox, sdk_key, config, diagnostic_accumulator, event_sender) @events_in_last_batch = 0 outbox = EventBuffer.new(config.capacity, config.logger) - flush_workers = NonBlockingThreadPool.new(MAX_FLUSH_WORKERS) + flush_workers = NonBlockingThreadPool.new(MAX_FLUSH_WORKERS, 'LD/EventDispatcher/FlushWorkers') if !@diagnostic_accumulator.nil? - diagnostic_event_workers = NonBlockingThreadPool.new(1) + diagnostic_event_workers = NonBlockingThreadPool.new(1, 'LD/EventDispatcher/DiagnosticEventWorkers') init_event = @diagnostic_accumulator.create_init_event(config) send_diagnostic_event(init_event, diagnostic_event_workers) else diagnostic_event_workers = nil end - Thread.new { main_loop(inbox, outbox, flush_workers, diagnostic_event_workers) } + Thread.new { main_loop(inbox, outbox, flush_workers, diagnostic_event_workers) }.name = "LD/EventDispatcher#main_loop" end private diff --git a/lib/ldclient-rb/impl/big_segments.rb b/lib/ldclient-rb/impl/big_segments.rb index 4a7efccf..ec19537a 100644 --- a/lib/ldclient-rb/impl/big_segments.rb +++ b/lib/ldclient-rb/impl/big_segments.rb @@ -24,7 +24,7 @@ def initialize(big_segments_config, logger) unless @store.nil? @cache = ExpiringCache.new(big_segments_config.context_cache_size, big_segments_config.context_cache_time) - @poll_worker = RepeatingTask.new(big_segments_config.status_poll_interval, 0, -> { poll_store_and_update_status }, logger) + @poll_worker = RepeatingTask.new(big_segments_config.status_poll_interval, 0, -> { poll_store_and_update_status }, logger, 'LD/BigSegments#status') @poll_worker.start end end diff --git a/lib/ldclient-rb/impl/integrations/file_data_source.rb b/lib/ldclient-rb/impl/integrations/file_data_source.rb index 1e7ad078..e009dc7d 100644 --- a/lib/ldclient-rb/impl/integrations/file_data_source.rb +++ b/lib/ldclient-rb/impl/integrations/file_data_source.rb @@ -216,6 +216,7 @@ def initialize(resolved_paths, interval, reloader, logger) end end end + @thread.name = "LD/FileDataSource" end def stop diff --git a/lib/ldclient-rb/impl/migrations/migrator.rb b/lib/ldclient-rb/impl/migrations/migrator.rb index 8fff0448..6b882acb 100644 --- a/lib/ldclient-rb/impl/migrations/migrator.rb +++ b/lib/ldclient-rb/impl/migrations/migrator.rb @@ -188,6 +188,9 @@ def write(key, context, default_stage, payload = nil) auth_handler = Thread.new { authoritative_result = authoritative.run } nonauth_handler = Thread.new { nonauthoritative_result = nonauthoritative.run } + auth_handler.name = "LD/Migrator#auth_handler" + nonauth_handler.name = "LD/Migrator#nonauth_handler" + auth_handler.join() nonauth_handler.join() when LaunchDarkly::Migrations::MigratorBuilder::EXECUTION_RANDOM && @sampler.sample(2) diff --git a/lib/ldclient-rb/impl/repeating_task.rb b/lib/ldclient-rb/impl/repeating_task.rb index 5fd0d029..a6335ae0 100644 --- a/lib/ldclient-rb/impl/repeating_task.rb +++ b/lib/ldclient-rb/impl/repeating_task.rb @@ -5,13 +5,16 @@ module LaunchDarkly module Impl class RepeatingTask - def initialize(interval, start_delay, task, logger) + attr_reader :name + + def initialize(interval, start_delay, task, logger, name) @interval = interval @start_delay = start_delay @task = task @logger = logger @stopped = Concurrent::AtomicBoolean.new(false) @worker = nil + @name = name end def start @@ -31,6 +34,8 @@ def start end end end + + @worker.name = @name end def stop diff --git a/lib/ldclient-rb/impl/store_client_wrapper.rb b/lib/ldclient-rb/impl/store_client_wrapper.rb index 1651c383..92c64e72 100644 --- a/lib/ldclient-rb/impl/store_client_wrapper.rb +++ b/lib/ldclient-rb/impl/store_client_wrapper.rb @@ -99,7 +99,7 @@ def monitoring_enabled? @logger.warn("Detected persistent store unavailability; updates will be cached until it recovers.") - task = Impl::RepeatingTask.new(0.5, 0, -> { self.check_availability }, @logger) + task = Impl::RepeatingTask.new(0.5, 0, -> { self.check_availability }, @logger, 'LD/StoreWrapper#check_availability') @mutex.synchronize do @poller = task diff --git a/lib/ldclient-rb/non_blocking_thread_pool.rb b/lib/ldclient-rb/non_blocking_thread_pool.rb index 06d644ec..5234bef1 100644 --- a/lib/ldclient-rb/non_blocking_thread_pool.rb +++ b/lib/ldclient-rb/non_blocking_thread_pool.rb @@ -8,9 +8,9 @@ module LaunchDarkly # than blocking. Also provides a way to wait for all jobs to finish without shutting down. # @private class NonBlockingThreadPool - def initialize(capacity) + def initialize(capacity, name = 'LD/NonBlockingThreadPool') @capacity = capacity - @pool = Concurrent::FixedThreadPool.new(capacity) + @pool = Concurrent::FixedThreadPool.new(capacity, name: name) @semaphore = Concurrent::Semaphore.new(capacity) end diff --git a/lib/ldclient-rb/polling.rb b/lib/ldclient-rb/polling.rb index 15dfb746..69963d20 100644 --- a/lib/ldclient-rb/polling.rb +++ b/lib/ldclient-rb/polling.rb @@ -13,7 +13,7 @@ def initialize(config, requestor) @initialized = Concurrent::AtomicBoolean.new(false) @started = Concurrent::AtomicBoolean.new(false) @ready = Concurrent::Event.new - @task = Impl::RepeatingTask.new(@config.poll_interval, 0, -> { self.poll }, @config.logger) + @task = Impl::RepeatingTask.new(@config.poll_interval, 0, -> { self.poll }, @config.logger, 'LD/PollingDataSource') end def initialized? diff --git a/spec/impl/repeating_task_spec.rb b/spec/impl/repeating_task_spec.rb index c970cb5a..debe68bc 100644 --- a/spec/impl/repeating_task_spec.rb +++ b/spec/impl/repeating_task_spec.rb @@ -11,9 +11,17 @@ def null_logger double.as_null_object end + it "can name the task" do + signal = Concurrent::Event.new + task = RepeatingTask.new(0.01, 0, -> { signal.set }, null_logger, "Junie B.") + + expect(task.name).to eq("Junie B.") + task.stop + end + it "does not start when created" do signal = Concurrent::Event.new - task = RepeatingTask.new(0.01, 0, -> { signal.set }, null_logger) + task = RepeatingTask.new(0.01, 0, -> { signal.set }, null_logger, "test") begin expect(signal.wait(0.1)).to be false ensure @@ -23,7 +31,7 @@ def null_logger it "executes until stopped" do queue = Queue.new - task = RepeatingTask.new(0.1, 0, -> { queue << Time.now }, null_logger) + task = RepeatingTask.new(0.1, 0, -> { queue << Time.now }, null_logger, "test") begin last = nil task.start @@ -62,7 +70,7 @@ def null_logger stopped.set end }, - null_logger) + null_logger, "test") begin task.start expect(stopped.wait(0.1)).to be true