Skip to content

Commit ade5a0f

Browse files
algolia-boteric-zahariaFluf22
committed
feat(ruby): expose maximum number of retries (generated)
algolia/api-clients-automation#6461 Co-authored-by: algolia-bot <accounts+algolia-api-client-bot@algolia.com> Co-authored-by: Eric Zaharia <94015633+eric-zaharia@users.noreply.github.com> Co-authored-by: Thomas Raffray <Fluf22@users.noreply.github.com>
1 parent 369f88b commit ade5a0f

4 files changed

Lines changed: 99 additions & 36 deletions

File tree

lib/algolia.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# frozen_string_literal: true
22

3-
# Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.
4-
53
# Common files
64
require "algolia/api_client"
75
require "algolia/api_error"
6+
require "algolia/chunked_helper_options"
87
require "algolia/defaults"
98
require "algolia/error"
109
require "algolia/version"

lib/algolia/api/ingestion_client.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3606,14 +3606,15 @@ def chunked_push(
36063606
wait_for_tasks = false,
36073607
batch_size = 1000,
36083608
reference_index_name = nil,
3609-
request_options = {}
3609+
request_options = {},
3610+
chunked_options = nil
36103611
)
36113612
responses = []
36123613
offset = 0
36133614
wait_batch_size = batch_size / 10
36143615
wait_batch_size = batch_size if wait_batch_size < 1
36153616
total_batches = (objects.length.to_f / batch_size).ceil
3616-
max_retries = 50
3617+
opts = Algolia::ChunkedHelperOptions.resolve(chunked_options)
36173618

36183619
objects.each_slice(batch_size).with_index do |chunk, batch_index|
36193620
response = push(
@@ -3641,7 +3642,13 @@ def chunked_push(
36413642
end
36423643

36433644
retries += 1
3644-
raise ApiError, "The maximum number of retries exceeded. (#{max_retries})" if retries >= max_retries
3645+
if retries >= opts.max_retries
3646+
raise(
3647+
ApiError,
3648+
"Stopped waiting for the task after #{opts.max_retries} retries. This does not mean the operation failed; it may still complete. If you need to keep polling, retry with a higher max_retries."
3649+
)
3650+
end
3651+
36453652
sleep([retries * 1.5, 5].min)
36463653
end
36473654
end

lib/algolia/api/search_client.rb

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3484,7 +3484,8 @@ def save_objects_with_transformation(
34843484
objects,
34853485
wait_for_tasks = false,
34863486
batch_size = 1000,
3487-
request_options = {}
3487+
request_options = {},
3488+
chunked_options = nil
34883489
)
34893490
assert_ingestion_transporter!
34903491

@@ -3495,7 +3496,8 @@ def save_objects_with_transformation(
34953496
wait_for_tasks,
34963497
batch_size,
34973498
nil,
3498-
request_options
3499+
request_options,
3500+
chunked_options
34993501
)
35003502
end
35013503

@@ -3517,7 +3519,8 @@ def partial_update_objects_with_transformation(
35173519
create_if_not_exists = false,
35183520
wait_for_tasks = false,
35193521
batch_size = 1000,
3520-
request_options = {}
3522+
request_options = {},
3523+
chunked_options = nil
35213524
)
35223525
assert_ingestion_transporter!
35233526

@@ -3530,7 +3533,8 @@ def partial_update_objects_with_transformation(
35303533
wait_for_tasks,
35313534
batch_size,
35323535
nil,
3533-
request_options
3536+
request_options,
3537+
chunked_options
35343538
)
35353539
end
35363540

@@ -3550,10 +3554,12 @@ def replace_all_objects_with_transformation(
35503554
objects,
35513555
batch_size = 1000,
35523556
scopes = [Search::ScopeType::SETTINGS, Search::ScopeType::RULES, Search::ScopeType::SYNONYMS],
3553-
request_options = {}
3557+
request_options = {},
3558+
chunked_options = nil
35543559
)
35553560
assert_ingestion_transporter!
35563561

3562+
opts = Algolia::ChunkedHelperOptions.resolve(chunked_options)
35573563
tmp_index_name = index_name + "_tmp_" + rand(10_000_000).to_s
35583564

35593565
begin
@@ -3574,10 +3580,11 @@ def replace_all_objects_with_transformation(
35743580
true,
35753581
batch_size,
35763582
index_name,
3577-
request_options
3583+
request_options,
3584+
opts
35783585
)
35793586

3580-
wait_for_task(tmp_index_name, copy_operation_response.task_id)
3587+
wait_for_task(tmp_index_name, copy_operation_response.task_id, opts.max_retries)
35813588

35823589
copy_operation_response = operation_index(
35833590
index_name,
@@ -3589,7 +3596,7 @@ def replace_all_objects_with_transformation(
35893596
request_options
35903597
)
35913598

3592-
wait_for_task(tmp_index_name, copy_operation_response.task_id)
3599+
wait_for_task(tmp_index_name, copy_operation_response.task_id, opts.max_retries)
35933600

35943601
move_operation_response = operation_index(
35953602
tmp_index_name,
@@ -3600,7 +3607,7 @@ def replace_all_objects_with_transformation(
36003607
request_options
36013608
)
36023609

3603-
wait_for_task(tmp_index_name, move_operation_response.task_id)
3610+
wait_for_task(tmp_index_name, move_operation_response.task_id, opts.max_retries)
36043611

36053612
search_watch_responses = watch_responses.map do |wr|
36063613
Search::WatchResponse.build_from_hash(wr.to_hash)
@@ -3622,14 +3629,14 @@ def replace_all_objects_with_transformation(
36223629
#
36233630
# @param index_name [String] the `index_name` where the operation was performed. (required)
36243631
# @param task_id [Integer] the `task_id` returned in the method response. (required)
3625-
# @param max_retries [Integer] the maximum number of retries. (optional, default to 50)
3632+
# @param max_retries [Integer] the maximum number of retries. (optional, default to Algolia::ChunkedHelperOptions::DEFAULT_MAX_RETRIES)
36263633
# @param timeout [Proc] the function to decide how long to wait between retries. (optional)
36273634
# @param request_options [Hash] the requestOptions to send along with the query, they will be forwarded to the `get_task` method.
36283635
# @return [Http::Response] the last get_task response
36293636
def wait_for_task(
36303637
index_name,
36313638
task_id,
3632-
max_retries = 50,
3639+
max_retries = Algolia::ChunkedHelperOptions::DEFAULT_MAX_RETRIES,
36333640
timeout = -> (retry_count) { [retry_count * 200, 5000].min },
36343641
request_options = {}
36353642
)
@@ -3644,19 +3651,22 @@ def wait_for_task(
36443651
sleep(timeout.call(retries) / 1000.0)
36453652
end
36463653

3647-
raise ApiError, "The maximum number of retries exceeded. (#{max_retries})"
3654+
raise(
3655+
ApiError,
3656+
"Stopped waiting for the task after #{max_retries} retries. This does not mean the operation failed; it may still complete. If you need to keep polling, retry with a higher max_retries."
3657+
)
36483658
end
36493659

36503660
# Helper: Wait for an application-level task to be published (completed) for a given `task_id`.
36513661
#
36523662
# @param task_id [Integer] the `task_id` returned in the method response. (required)
3653-
# @param max_retries [Integer] the maximum number of retries. (optional, default to 50)
3663+
# @param max_retries [Integer] the maximum number of retries. (optional, default to Algolia::ChunkedHelperOptions::DEFAULT_MAX_RETRIES)
36543664
# @param timeout [Proc] the function to decide how long to wait between retries. (optional)
36553665
# @param request_options [Hash] the requestOptions to send along with the query, they will be forwarded to the `get_task` method.
36563666
# @return [Http::Response] the last get_task response
36573667
def wait_for_app_task(
36583668
task_id,
3659-
max_retries = 50,
3669+
max_retries = Algolia::ChunkedHelperOptions::DEFAULT_MAX_RETRIES,
36603670
timeout = -> (retry_count) { [retry_count * 200, 5000].min },
36613671
request_options = {}
36623672
)
@@ -3671,7 +3681,10 @@ def wait_for_app_task(
36713681
sleep(timeout.call(retries) / 1000.0)
36723682
end
36733683

3674-
raise ApiError, "The maximum number of retries exceeded. (#{max_retries})"
3684+
raise(
3685+
ApiError,
3686+
"Stopped waiting for the task after #{max_retries} retries. This does not mean the operation failed; it may still complete. If you need to keep polling, retry with a higher max_retries."
3687+
)
36753688
end
36763689

36773690
# Helper: Wait for an API key to be added, updated or deleted based on a given `operation`.
@@ -3687,7 +3700,7 @@ def wait_for_api_key(
36873700
key,
36883701
operation,
36893702
api_key = Search::ApiKey.new,
3690-
max_retries = 50,
3703+
max_retries = Algolia::ChunkedHelperOptions::DEFAULT_MAX_RETRIES,
36913704
timeout = -> (retry_count) { [retry_count * 200, 5000].min },
36923705
request_options = {}
36933706
)
@@ -3710,7 +3723,10 @@ def wait_for_api_key(
37103723
sleep(timeout.call(retries) / 1000.0)
37113724
end
37123725

3713-
raise ApiError, "The maximum number of retries exceeded. (#{max_retries})"
3726+
raise(
3727+
ApiError,
3728+
"Stopped waiting for the task after #{max_retries} retries. This does not mean the operation failed; it may still complete. If you need to keep polling, retry with a higher max_retries."
3729+
)
37143730
end
37153731

37163732
while retries < max_retries
@@ -3729,7 +3745,10 @@ def wait_for_api_key(
37293745
sleep(timeout.call(retries) / 1000.0)
37303746
end
37313747

3732-
raise ApiError, "The maximum number of retries exceeded. (#{max_retries})"
3748+
raise(
3749+
ApiError,
3750+
"Stopped waiting for the task after #{max_retries} retries. This does not mean the operation failed; it may still complete. If you need to keep polling, retry with a higher max_retries."
3751+
)
37333752
end
37343753

37353754
# Helper: Iterate on the `browse` method of the client to allow aggregating objects of an index.
@@ -3907,14 +3926,22 @@ def get_secured_api_key_remaining_validity(secured_api_key)
39073926
#
39083927
# @return [BatchResponse]
39093928
#
3910-
def save_objects(index_name, objects, wait_for_tasks = false, batch_size = 1000, request_options = {})
3929+
def save_objects(
3930+
index_name,
3931+
objects,
3932+
wait_for_tasks = false,
3933+
batch_size = 1000,
3934+
request_options = {},
3935+
chunked_options = nil
3936+
)
39113937
chunked_batch(
39123938
index_name,
39133939
objects,
39143940
Search::Action::ADD_OBJECT,
39153941
wait_for_tasks,
39163942
batch_size,
3917-
request_options
3943+
request_options,
3944+
chunked_options
39183945
)
39193946
end
39203947

@@ -3928,14 +3955,22 @@ def save_objects(index_name, objects, wait_for_tasks = false, batch_size = 1000,
39283955
#
39293956
# @return [BatchResponse]
39303957
#
3931-
def delete_objects(index_name, object_ids, wait_for_tasks = false, batch_size = 1000, request_options = {})
3958+
def delete_objects(
3959+
index_name,
3960+
object_ids,
3961+
wait_for_tasks = false,
3962+
batch_size = 1000,
3963+
request_options = {},
3964+
chunked_options = nil
3965+
)
39323966
chunked_batch(
39333967
index_name,
39343968
object_ids.map { |id| {"objectID" => id} },
39353969
Search::Action::DELETE_OBJECT,
39363970
wait_for_tasks,
39373971
batch_size,
3938-
request_options
3972+
request_options,
3973+
chunked_options
39393974
)
39403975
end
39413976

@@ -3956,15 +3991,17 @@ def partial_update_objects(
39563991
create_if_not_exists,
39573992
wait_for_tasks = false,
39583993
batch_size = 1000,
3959-
request_options = {}
3994+
request_options = {},
3995+
chunked_options = nil
39603996
)
39613997
chunked_batch(
39623998
index_name,
39633999
objects,
39644000
create_if_not_exists ? Search::Action::PARTIAL_UPDATE_OBJECT : Search::Action::PARTIAL_UPDATE_OBJECT_NO_CREATE,
39654001
wait_for_tasks,
39664002
batch_size,
3967-
request_options
4003+
request_options,
4004+
chunked_options
39684005
)
39694006
end
39704007

@@ -3985,8 +4022,10 @@ def chunked_batch(
39854022
action = Action::ADD_OBJECT,
39864023
wait_for_tasks = false,
39874024
batch_size = 1000,
3988-
request_options = {}
4025+
request_options = {},
4026+
chunked_options = nil
39894027
)
4028+
opts = Algolia::ChunkedHelperOptions.resolve(chunked_options)
39904029
responses = []
39914030
objects.each_slice(batch_size) do |chunk|
39924031
requests = chunk.map do |object|
@@ -3998,7 +4037,7 @@ def chunked_batch(
39984037

39994038
if wait_for_tasks
40004039
responses.each do |response|
4001-
wait_for_task(index_name, response.task_id)
4040+
wait_for_task(index_name, response.task_id, opts.max_retries)
40024041
end
40034042
end
40044043

@@ -4019,8 +4058,10 @@ def replace_all_objects(
40194058
objects,
40204059
batch_size = 1000,
40214060
scopes = [Search::ScopeType::SETTINGS, Search::ScopeType::RULES, Search::ScopeType::SYNONYMS],
4022-
request_options = {}
4061+
request_options = {},
4062+
chunked_options = nil
40234063
)
4064+
opts = Algolia::ChunkedHelperOptions.resolve(chunked_options)
40244065
tmp_index_name = index_name + "_tmp_" + rand(10_000_000).to_s
40254066

40264067
begin
@@ -4040,10 +4081,11 @@ def replace_all_objects(
40404081
Search::Action::ADD_OBJECT,
40414082
true,
40424083
batch_size,
4043-
request_options
4084+
request_options,
4085+
opts
40444086
)
40454087

4046-
wait_for_task(tmp_index_name, copy_operation_response.task_id)
4088+
wait_for_task(tmp_index_name, copy_operation_response.task_id, opts.max_retries)
40474089

40484090
copy_operation_response = operation_index(
40494091
index_name,
@@ -4055,7 +4097,7 @@ def replace_all_objects(
40554097
request_options
40564098
)
40574099

4058-
wait_for_task(tmp_index_name, copy_operation_response.task_id)
4100+
wait_for_task(tmp_index_name, copy_operation_response.task_id, opts.max_retries)
40594101

40604102
move_operation_response = operation_index(
40614103
tmp_index_name,
@@ -4066,7 +4108,7 @@ def replace_all_objects(
40664108
request_options
40674109
)
40684110

4069-
wait_for_task(tmp_index_name, move_operation_response.task_id)
4111+
wait_for_task(tmp_index_name, move_operation_response.task_id, opts.max_retries)
40704112

40714113
Search::ReplaceAllObjectsResponse.new(
40724114
copy_operation_response: copy_operation_response,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module Algolia
2+
# Optional configuration for chunked helpers that batch records and poll for task completion.
3+
class ChunkedHelperOptions
4+
DEFAULT_MAX_RETRIES = 100
5+
attr_reader :max_retries
6+
7+
def initialize(max_retries: DEFAULT_MAX_RETRIES)
8+
@max_retries = max_retries
9+
end
10+
11+
def self.resolve(options)
12+
options || new
13+
end
14+
end
15+
end

0 commit comments

Comments
 (0)