Skip to content

Commit fe80913

Browse files
committed
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
1 parent 7bda933 commit fe80913

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

google_maps_service_ruby.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ Gem::Specification.new do |spec|
2323
spec.require_paths = ["lib"]
2424

2525
spec.add_runtime_dependency "multi_json", "~> 1.15"
26-
spec.add_runtime_dependency "retriable", "~> 3.1"
2726
spec.add_runtime_dependency "base64"
2827

2928
spec.add_development_dependency "coveralls_reborn", "~> 0.25.0"

lib/google_maps_service/client.rb

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require "multi_json"
22
require "net/http"
3-
require "retriable"
43
require "google_maps_service/errors"
54
require "google_maps_service/convert"
65
require "google_maps_service/url"
@@ -101,6 +100,45 @@ def client
101100

102101
protected
103102

103+
# Retry a block of code with exponential backoff on specific errors.
104+
#
105+
# @param [Integer] timeout Maximum time in seconds to retry (nil for no timeout).
106+
# @param [Array<Class>] on Array of error classes to retry on.
107+
# @yield Block to retry.
108+
#
109+
# @return [Object] Result of the block.
110+
def with_retry(timeout: nil, on: [])
111+
start_time = Time.now
112+
attempt = 0
113+
base_delay = 0.5
114+
max_delay = 60
115+
116+
loop do
117+
begin
118+
return yield
119+
rescue *on => e
120+
attempt += 1
121+
elapsed = Time.now - start_time
122+
123+
if timeout && elapsed >= timeout
124+
raise e
125+
end
126+
127+
# Exponential backoff: 0.5, 0.75, 1.125, 1.6875, ...
128+
delay = [base_delay * (1.5**(attempt - 1)), max_delay].min
129+
130+
# Don't sleep longer than the remaining timeout
131+
if timeout
132+
remaining = timeout - elapsed
133+
delay = [delay, remaining].min
134+
raise e if delay <= 0
135+
end
136+
137+
sleep delay
138+
end
139+
end
140+
end
141+
104142
# Initialize QPS queue. QPS queue is a "tickets" for calling API
105143
def initialize_query_tickets
106144
if @queries_per_second
@@ -137,7 +175,7 @@ def user_agent
137175
def get(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custom_response_decoder: nil)
138176
url = URI(base_url + generate_auth_url(path, params, accepts_client_id))
139177

140-
Retriable.retriable timeout: @retry_timeout, on: RETRIABLE_ERRORS do |try|
178+
with_retry(timeout: @retry_timeout, on: RETRIABLE_ERRORS) do
141179
begin
142180
request_query_ticket
143181
request = Net::HTTP::Get.new(url)
@@ -166,7 +204,7 @@ def get(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custo
166204
def post(path, params, base_url: DEFAULT_BASE_URL, accepts_client_id: true, custom_response_decoder: nil, field_mask: nil)
167205
url = URI(base_url + generate_auth_url(path, {}, accepts_client_id))
168206

169-
Retriable.retriable timeout: @retry_timeout, on: RETRIABLE_ERRORS do |try|
207+
with_retry(timeout: @retry_timeout, on: RETRIABLE_ERRORS) do
170208
begin
171209
request_query_ticket
172210
request = Net::HTTP::Post.new(url)

0 commit comments

Comments
 (0)