lib/ldclient-rb/impl/event_sender.rb in launchdarkly-server-sdk-5.8.2 vs lib/ldclient-rb/impl/event_sender.rb in launchdarkly-server-sdk-6.0.0

- old
+ new

@@ -1,71 +1,87 @@ +require "ldclient-rb/impl/unbounded_pool" + require "securerandom" +require "http" module LaunchDarkly module Impl EventSenderResult = Struct.new(:success, :must_shutdown, :time_from_server) class EventSender CURRENT_SCHEMA_VERSION = 3 DEFAULT_RETRY_INTERVAL = 1 def initialize(sdk_key, config, http_client = nil, retry_interval = DEFAULT_RETRY_INTERVAL) - @client = http_client ? http_client : LaunchDarkly::Util.new_http_client(config.events_uri, config) @sdk_key = sdk_key @config = config @events_uri = config.events_uri + "/bulk" @diagnostic_uri = config.events_uri + "/diagnostic" @logger = config.logger @retry_interval = retry_interval + @http_client_pool = UnboundedPool.new( + lambda { LaunchDarkly::Util.new_http_client(@config.events_uri, @config) }, + lambda { |client| client.close }) end + def stop + @http_client_pool.dispose_all() + end + def send_event_data(event_data, description, is_diagnostic) uri = is_diagnostic ? @diagnostic_uri : @events_uri payload_id = is_diagnostic ? nil : SecureRandom.uuid - res = nil - (0..1).each do |attempt| - if attempt > 0 - @logger.warn { "[LDClient] Will retry posting events after #{@retry_interval} second" } - sleep(@retry_interval) - end - begin - @client.start if !@client.started? - @logger.debug { "[LDClient] sending #{description}: #{event_data}" } - req = Net::HTTP::Post.new(uri) - req.content_type = "application/json" - req.body = event_data - Impl::Util.default_http_headers(@sdk_key, @config).each { |k, v| req[k] = v } - if !is_diagnostic - req["X-LaunchDarkly-Event-Schema"] = CURRENT_SCHEMA_VERSION.to_s - req["X-LaunchDarkly-Payload-ID"] = payload_id + begin + http_client = @http_client_pool.acquire() + response = nil + (0..1).each do |attempt| + if attempt > 0 + @logger.warn { "[LDClient] Will retry posting events after #{@retry_interval} second" } + sleep(@retry_interval) end - req["Connection"] = "keep-alive" - res = @client.request(req) - rescue StandardError => exn - @logger.warn { "[LDClient] Error sending events: #{exn.inspect}." } - next - end - status = res.code.to_i - if status >= 200 && status < 300 - res_time = nil - if !res["date"].nil? - begin - res_time = Time.httpdate(res["date"]) - rescue ArgumentError + begin + @logger.debug { "[LDClient] sending #{description}: #{event_data}" } + headers = {} + headers["content-type"] = "application/json" + Impl::Util.default_http_headers(@sdk_key, @config).each { |k, v| headers[k] = v } + if !is_diagnostic + headers["X-LaunchDarkly-Event-Schema"] = CURRENT_SCHEMA_VERSION.to_s + headers["X-LaunchDarkly-Payload-ID"] = payload_id end + response = http_client.request("POST", uri, { + headers: headers, + body: event_data + }) + rescue StandardError => exn + @logger.warn { "[LDClient] Error sending events: #{exn.inspect}." } + next end - return EventSenderResult.new(true, false, res_time) + status = response.status.code + # must fully read body for persistent connections + body = response.to_s + if status >= 200 && status < 300 + res_time = nil + if !response.headers["date"].nil? + begin + res_time = Time.httpdate(response.headers["date"]) + rescue ArgumentError + end + end + return EventSenderResult.new(true, false, res_time) + end + must_shutdown = !LaunchDarkly::Util.http_error_recoverable?(status) + can_retry = !must_shutdown && attempt == 0 + message = LaunchDarkly::Util.http_error_message(status, "event delivery", can_retry ? "will retry" : "some events were dropped") + @logger.error { "[LDClient] #{message}" } + if must_shutdown + return EventSenderResult.new(false, true, nil) + end end - must_shutdown = !LaunchDarkly::Util.http_error_recoverable?(status) - can_retry = !must_shutdown && attempt == 0 - message = LaunchDarkly::Util.http_error_message(status, "event delivery", can_retry ? "will retry" : "some events were dropped") - @logger.error { "[LDClient] #{message}" } - if must_shutdown - return EventSenderResult.new(false, true, nil) - end + # used up our retries + return EventSenderResult.new(false, false, nil) + ensure + @http_client_pool.release(http_client) end - # used up our retries - return EventSenderResult.new(false, false, nil) end end end end