From 6843328b1b94ea4197023e29cc7e4608c63a437e Mon Sep 17 00:00:00 2001 From: Pierre Millot Date: Thu, 19 May 2022 17:29:16 +0200 Subject: [PATCH 1/3] feat(java): waitForTask --- .../AlgoliaRetriesExceededException.java | 22 +++++++ .../java/com/algolia/utils/TaskUtils.java | 62 +++++++++++++++++++ .../src/createRetryablePromise.ts | 4 +- .../algolia/codegen/AlgoliaJavaGenerator.java | 4 ++ .../java/libraries/okhttp-gson/api.mustache | 14 +++++ 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/exceptions/AlgoliaRetriesExceededException.java create mode 100644 clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java diff --git a/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/exceptions/AlgoliaRetriesExceededException.java b/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/exceptions/AlgoliaRetriesExceededException.java new file mode 100644 index 0000000000..aed6ac50c2 --- /dev/null +++ b/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/exceptions/AlgoliaRetriesExceededException.java @@ -0,0 +1,22 @@ +package com.algolia.exceptions; + +/** + * Exception thrown when an error occurs during the waitForTask strategy. For example: maximum + * number of retry exceeded + */ +public class AlgoliaRetriesExceededException extends AlgoliaRuntimeException { + + public static final long serialVersionUID = 1L; + + public AlgoliaRetriesExceededException(String message, Throwable cause) { + super(message, cause); + } + + public AlgoliaRetriesExceededException(String message) { + super(message); + } + + public AlgoliaRetriesExceededException(Throwable cause) { + super(cause); + } +} diff --git a/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java b/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java new file mode 100644 index 0000000000..d19d685e5c --- /dev/null +++ b/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java @@ -0,0 +1,62 @@ +package com.algolia.utils; + +import com.algolia.exceptions.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.function.IntUnaryOperator; +import java.util.function.Predicate; +import java.util.function.Supplier; + +public class TaskUtils { + + public static void retryUntil( + Supplier> func, + Predicate validate, + int maxTrial, + IntUnaryOperator timeout + ) throws AlgoliaRuntimeException { + int retryCount = 0; + while (retryCount < maxTrial) { + try { + TResponse resp = func.get().get(); + System.out.println(resp); + if (validate.test(resp)) { + return; + } + } catch (InterruptedException | ExecutionException e) { + // if the task is interrupted, just return + return; + } + try { + System.out.println("sleeping for " + timeout.applyAsInt(retryCount)); + Thread.sleep(timeout.applyAsInt(retryCount)); + } catch (InterruptedException ignored) { + // Restore interrupted state... + Thread.currentThread().interrupt(); + } + + retryCount++; + } + throw new AlgoliaRetriesExceededException( + "The maximum number of trials exceeded. (" + + (retryCount + 1) + + "/" + + maxTrial + + ")" + ); + } + + public static void retryUntil( + Supplier> func, + Predicate validate + ) { + retryUntil( + func, + validate, + 50, + (int retries) -> { + return Math.min(retries * 200, 5000); + } + ); + } +} diff --git a/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts b/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts index 73bb69e73f..85582d34ca 100644 --- a/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts +++ b/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts @@ -12,8 +12,8 @@ import type { CreateRetryablePromiseOptions } from './types/CreateRetryablePromi export function createRetryablePromise({ func, validate, - maxTrial = 10, - timeout = (retryCount: number): number => Math.min(retryCount * 10, 1000), + maxTrial = 50, + timeout = (retryCount: number): number => Math.min(retryCount * 200, 5000), }: CreateRetryablePromiseOptions): Promise { let retryCount = 0; const retry = (): Promise => { diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java index b2e39aea23..7f5d6736b8 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java @@ -50,6 +50,10 @@ public Map postProcessOperationsWithModels( Utils.getClientNameKebabCase(results), additionalProperties ); + additionalProperties.put( + "isSearchClient", + Utils.getClientNameKebabCase(results).equals("search") + ); additionalProperties.put( "packageVersion", Utils.getClientConfigField("java", "packageVersion") diff --git a/templates/java/libraries/okhttp-gson/api.mustache b/templates/java/libraries/okhttp-gson/api.mustache index 74033b6e85..ba173c5c33 100644 --- a/templates/java/libraries/okhttp-gson/api.mustache +++ b/templates/java/libraries/okhttp-gson/api.mustache @@ -216,5 +216,19 @@ public class {{classname}} extends ApiClient { } {{/optionalParams.0}} {{/operation}} + + {{#isSearchClient}} + public void waitForTask(String indexName, Long taskID, RequestOptions requestOptions) { + TaskUtils.retryUntil(() -> { + return this.getTaskAsync(indexName, taskID, requestOptions); + }, (GetTaskResponse task) -> { + return task.getStatus() == TaskStatus.PUBLISHED; + }); + } + + public void waitForTask(String indexName, Long taskID) { + this.waitForTask(indexName, taskID, null); + } + {{/isSearchClient}} } {{/operations}} From 4822dcf350f8851cfc7c0eea88adf19f0f0ecf49 Mon Sep 17 00:00:00 2001 From: Pierre Millot Date: Fri, 20 May 2022 11:18:38 +0200 Subject: [PATCH 2/3] review --- .../java/com/algolia/utils/TaskUtils.java | 21 +++++-------------- .../src/createRetryablePromise.ts | 8 +++++-- .../java/libraries/okhttp-gson/api.mustache | 15 ++++++++++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java b/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java index d19d685e5c..42a18395a9 100644 --- a/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java +++ b/clients/algoliasearch-client-java-2/algoliasearch-core/src/main/java/com/algolia/utils/TaskUtils.java @@ -9,6 +9,11 @@ public class TaskUtils { + public static final int DEFAULT_MAX_TRIAL = 50; + public static final IntUnaryOperator DEFAULT_TIMEOUT = (int retries) -> { + return Math.min(retries * 200, 5000); + }; + public static void retryUntil( Supplier> func, Predicate validate, @@ -19,7 +24,6 @@ public static void retryUntil( while (retryCount < maxTrial) { try { TResponse resp = func.get().get(); - System.out.println(resp); if (validate.test(resp)) { return; } @@ -28,7 +32,6 @@ public static void retryUntil( return; } try { - System.out.println("sleeping for " + timeout.applyAsInt(retryCount)); Thread.sleep(timeout.applyAsInt(retryCount)); } catch (InterruptedException ignored) { // Restore interrupted state... @@ -45,18 +48,4 @@ public static void retryUntil( ")" ); } - - public static void retryUntil( - Supplier> func, - Predicate validate - ) { - retryUntil( - func, - validate, - 50, - (int retries) -> { - return Math.min(retries * 200, 5000); - } - ); - } } diff --git a/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts b/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts index 85582d34ca..990c3a6fb2 100644 --- a/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts +++ b/clients/algoliasearch-client-javascript/packages/client-common/src/createRetryablePromise.ts @@ -1,5 +1,9 @@ import type { CreateRetryablePromiseOptions } from './types/CreateRetryablePromise'; +export const DEFAULT_MAX_TRIAL = 50; +export const DEFAULT_TIMEOUT = (retryCount: number): number => + Math.min(retryCount * 200, 5000); + /** * Return a promise that retry a task until it meets the condition. * @@ -12,8 +16,8 @@ import type { CreateRetryablePromiseOptions } from './types/CreateRetryablePromi export function createRetryablePromise({ func, validate, - maxTrial = 50, - timeout = (retryCount: number): number => Math.min(retryCount * 200, 5000), + maxTrial = DEFAULT_MAX_TRIAL, + timeout = DEFAULT_TIMEOUT, }: CreateRetryablePromiseOptions): Promise { let retryCount = 0; const retry = (): Promise => { diff --git a/templates/java/libraries/okhttp-gson/api.mustache b/templates/java/libraries/okhttp-gson/api.mustache index ba173c5c33..df3ba1dc38 100644 --- a/templates/java/libraries/okhttp-gson/api.mustache +++ b/templates/java/libraries/okhttp-gson/api.mustache @@ -13,6 +13,7 @@ import com.algolia.exceptions.*; import com.algolia.utils.retry.CallType; import com.algolia.utils.retry.StatefulHost; import com.algolia.utils.RequestOptions; +import java.util.function.IntUnaryOperator; import java.util.EnumSet; import java.util.Random; @@ -218,16 +219,24 @@ public class {{classname}} extends ApiClient { {{/operation}} {{#isSearchClient}} - public void waitForTask(String indexName, Long taskID, RequestOptions requestOptions) { + public void waitForTask(String indexName, Long taskID, RequestOptions requestOptions, int maxTrial, IntUnaryOperator timeout) { TaskUtils.retryUntil(() -> { return this.getTaskAsync(indexName, taskID, requestOptions); }, (GetTaskResponse task) -> { return task.getStatus() == TaskStatus.PUBLISHED; - }); + }, maxTrial, timeout); + } + + public void waitForTask(String indexName, Long taskID, RequestOptions requestOptions) { + this.waitForTask(indexName, taskID, requestOptions, TaskUtils.DEFAULT_MAX_TRIAL, TaskUtils.DEFAULT_TIMEOUT); + } + + public void waitForTask(String indexName, Long taskID, int maxTrial, IntUnaryOperator timeout) { + this.waitForTask(indexName, taskID, null, maxTrial, timeout); } public void waitForTask(String indexName, Long taskID) { - this.waitForTask(indexName, taskID, null); + this.waitForTask(indexName, taskID, null, TaskUtils.DEFAULT_MAX_TRIAL, TaskUtils.DEFAULT_TIMEOUT); } {{/isSearchClient}} } From 9ad8c27da1233095385ff2758fb2fe50f727a177 Mon Sep 17 00:00:00 2001 From: Pierre Millot Date: Fri, 20 May 2022 11:47:07 +0200 Subject: [PATCH 3/3] fix js utils --- .github/workflows/check.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 3ad09d5afe..0d047a0717 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -199,8 +199,9 @@ jobs: with: type: specs + # Always download the utils for js, in case they changed we want to include them in the zip - name: Download JavaScript utils artifacts - if: ${{ matrix.client.language == 'javascript' && steps.cache.outputs.cache-hit != 'true' }} + if: ${{ matrix.client.language == 'javascript' }} uses: ./.github/actions/restore-artifacts with: type: js_utils