Class: Crystil::Collector
- Inherits:
-
Object
- Object
- Crystil::Collector
- Defined in:
- lib/crystil/collector.rb,
sig/crystil/collector.rbs
Overview
Handles asynchronous submission of analytics to Crystil collector
Constant Summary collapse
- DEFAULT_MAX_RETRIES =
3- RETRY_DELAY =
seconds
1
Instance Method Summary collapse
-
#initialize(config) ⇒ Collector
constructor
A new instance of Collector.
- #post_to_collector(payload) ⇒ Object
-
#shutdown ⇒ void
Gracefully shutdown the collector.
-
#submit(payload) ⇒ Object
Submit analytics payload synchronously (for testing).
-
#submit_async(payload) ⇒ void
Submit analytics payload asynchronously.
- #submit_with_retry(payload, attempt = 1) ⇒ Object
Constructor Details
#initialize(config) ⇒ Collector
Returns a new instance of Collector.
14 15 16 17 18 19 20 21 22 |
# File 'lib/crystil/collector.rb', line 14 def initialize(config) @config = config @executor = Concurrent::ThreadPoolExecutor.new( min_threads: 1, max_threads: 5, max_queue: 100, fallback_policy: :discard ) end |
Instance Method Details
#post_to_collector(payload) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/crystil/collector.rb', line 65 def post_to_collector(payload) uri = URI.parse(@config.collector_url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = uri.scheme == "https" # Configure SSL to use system certificates if http.use_ssl? http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.cert_store = OpenSSL::X509::Store.new http.cert_store.set_default_paths end http.open_timeout = @config.timeout http.read_timeout = @config.timeout request = Net::HTTP::Post.new("/rec") request["Content-Type"] = "application/json" request["User-Agent"] = "crystil-ruby/#{@config.version}" request.body = JSON.generate(payload) http.request(request) end |
#shutdown ⇒ void
This method returns an undefined value.
Gracefully shutdown the collector
39 40 41 42 |
# File 'lib/crystil/collector.rb', line 39 def shutdown @executor.shutdown @executor.wait_for_termination(5) end |
#submit(payload) ⇒ Object
Submit analytics payload synchronously (for testing)
34 35 36 |
# File 'lib/crystil/collector.rb', line 34 def submit(payload) submit_with_retry(payload) end |
#submit_async(payload) ⇒ void
This method returns an undefined value.
Submit analytics payload asynchronously
25 26 27 28 29 30 31 |
# File 'lib/crystil/collector.rb', line 25 def submit_async(payload) @executor.post do submit_with_retry(payload) rescue StandardError => e warn "Crystil: Failed to submit analytics: #{e.}" end end |
#submit_with_retry(payload, attempt = 1) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/crystil/collector.rb', line 46 def submit_with_retry(payload, attempt = 1) response = post_to_collector(payload) unless response.is_a?(Net::HTTPSuccess) raise APIError.new( "Collector request failed: #{response.code} #{response.}", status_code: response.code.to_i, response_body: response.body ) end response rescue StandardError => e raise e unless attempt < DEFAULT_MAX_RETRIES sleep(RETRY_DELAY * attempt) submit_with_retry(payload, attempt + 1) end |