From fe809138b2792f5dd44ee34caf2ee5cebdf1e019 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 5 Jan 2026 18:32:57 +0000 Subject: [PATCH] Remove dependency on retriable gem and implement custom retry mechanism - Remove retriable gem from runtime dependencies in gemspec - Remove require statement for retriable in client.rb - Implement custom with_retry method with exponential backoff - Replace Retriable.retriable calls with custom with_retry method - Maintains same retry behavior for ServerError and RateLimitError - Uses exponential backoff: 0.5s, 0.75s, 1.125s, 1.6875s, ... up to 60s max - Respects retry_timeout configuration --- google_maps_service_ruby.gemspec | 1 - lib/google_maps_service/client.rb | 44 ++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/google_maps_service_ruby.gemspec b/google_maps_service_ruby.gemspec index 95794e4..9c83ad1 100644 --- a/google_maps_service_ruby.gemspec +++ b/google_maps_service_ruby.gemspec @@ -23,7 +23,6 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.add_runtime_dependency "multi_json", "~> 1.15" - spec.add_runtime_dependency "retriable", "~> 3.1" spec.add_runtime_dependency "base64" spec.add_development_dependency "coveralls_reborn", "~> 0.25.0" diff --git a/lib/google_maps_service/client.rb b/lib/google_maps_service/client.rb index 1a4d926..d9b7de9 100644 --- a/lib/google_maps_service/client.rb +++ b/lib/google_maps_service/client.rb @@ -1,6 +1,5 @@ require "multi_json" require "net/http" -require "retriable" require "google_maps_service/errors" require "google_maps_service/convert" require "google_maps_service/url" @@ -101,6 +100,45 @@ def client protected + # Retry a block of code with exponential backoff on specific errors. + # + # @param [Integer] timeout Maximum time in seconds to retry (nil for no timeout). + # @param [Array] on Array of error classes to retry on. + # @yield Block to retry. + # + # @return [Object] Result of the block. + def with_retry(timeout: nil, on: []) + start_time = Time.now + attempt = 0 + base_delay = 0.5 + max_delay = 60 + + loop do + begin + return yield + rescue *on => e + attempt += 1 + elapsed = Time.now - start_time + + if timeout && elapsed >= timeout + raise e + end + + # Exponential backoff: 0.5, 0.75, 1.125, 1.6875, ... + delay = [base_delay * (1.5**(attempt - 1)), max_delay].min + + # Don't sleep longer than the remaining timeout + if timeout + remaining = timeout - elapsed + delay = [delay, remaining].min + raise e if delay <= 0 + end + + sleep delay + end + end + end + # Initialize QPS queue. QPS queue is a "tickets" for calling API def initialize_query_tickets if @queries_per_second @@ -137,7 +175,7 @@ def user_agent def get(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custom_response_decoder: nil) url = URI(base_url + generate_auth_url(path, params, accepts_client_id)) - Retriable.retriable timeout: @retry_timeout, on: RETRIABLE_ERRORS do |try| + with_retry(timeout: @retry_timeout, on: RETRIABLE_ERRORS) do begin request_query_ticket request = Net::HTTP::Get.new(url) @@ -166,7 +204,7 @@ def get(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custo def post(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custom_response_decoder: nil, field_mask: nil) url = URI(base_url + generate_auth_url(path, {}, accepts_client_id)) - Retriable.retriable timeout: @retry_timeout, on: RETRIABLE_ERRORS do |try| + with_retry(timeout: @retry_timeout, on: RETRIABLE_ERRORS) do begin request_query_ticket request = Net::HTTP::Post.new(url)