Skip to content

Commit

Permalink
fix(orchestrator): increase the number of attempts to fetch the insta…
Browse files Browse the repository at this point in the history
…nce after execution (janus-idp#1301)

fix(orchestrator): increase the number of attempts to fetch the instance
  • Loading branch information
caponetto authored Mar 4, 2024
1 parent e5c33c0 commit 77dcce3
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
49 changes: 49 additions & 0 deletions plugins/orchestrator-backend/src/service/Helper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { retryAsyncFunction } from './Helper';

describe('retryAsyncFunction', () => {
const successfulResponse = 'Success';
it('should be successful in the first attempt', async () => {
const asyncFnSuccess = jest.fn().mockResolvedValueOnce(successfulResponse);

const result = await retryAsyncFunction({
asyncFn: asyncFnSuccess,
maxAttempts: 3,
delayMs: 100,
});

expect(result).toBe(successfulResponse);
expect(asyncFnSuccess).toHaveBeenCalledTimes(1);
});

it('should throw an error after maximum attempts', async () => {
const asyncFnFailure = jest.fn().mockResolvedValue(undefined);

await expect(
retryAsyncFunction({
asyncFn: asyncFnFailure,
maxAttempts: 5,
delayMs: 100,
}),
).rejects.toThrow();

expect(asyncFnFailure).toHaveBeenCalledTimes(5);
});

it('should retry until successful after getting some undefined responses', async () => {
const asyncFns = jest
.fn()
.mockResolvedValueOnce(undefined)
.mockResolvedValueOnce(undefined)
.mockResolvedValueOnce(undefined)
.mockResolvedValueOnce(successfulResponse);

const result = await retryAsyncFunction({
asyncFn: asyncFns,
maxAttempts: 5,
delayMs: 100,
});

expect(result).toBe(successfulResponse);
expect(asyncFns).toHaveBeenCalledTimes(4);
});
});
12 changes: 5 additions & 7 deletions plugins/orchestrator-backend/src/service/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,19 @@ import { Logger } from 'winston';
import os from 'os';

export async function retryAsyncFunction<T>(args: {
asyncFunc: () => Promise<T | undefined>;
retries: number;
asyncFn: () => Promise<T | undefined>;
maxAttempts: number;
delayMs: number;
}): Promise<T> {
let result: T | undefined;
for (let i = 0; i < args.retries; i++) {
result = await args.asyncFunc();
for (let i = 0; i < args.maxAttempts; i++) {
result = await args.asyncFn();
if (result !== undefined) {
return result;
}
await new Promise(resolve => setTimeout(resolve, args.delayMs));
}
throw new Error(
`Exceeded maximum number of retries for function ${args.asyncFunc.name}`,
);
throw new Error('Exceeded maximum number of retries for async function');
}

export async function getWorkingDirectory(
Expand Down
6 changes: 3 additions & 3 deletions plugins/orchestrator-backend/src/service/api/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DataIndexService } from '../DataIndexService';
import { retryAsyncFunction } from '../Helper';
import { SonataFlowService } from '../SonataFlowService';

const FETCH_INSTANCE_MAX_RETRIES = 5;
const FETCH_INSTANCE_MAX_ATTEMPTS = 10;
const FETCH_INSTANCE_RETRY_DELAY_MS = 1000;

export namespace V1 {
Expand Down Expand Up @@ -138,9 +138,9 @@ export namespace V1 {

// Making sure the instance data is available before returning
await retryAsyncFunction({
asyncFunc: () =>
asyncFn: () =>
dataIndexService.fetchProcessInstance(executionResponse.id),
retries: FETCH_INSTANCE_MAX_RETRIES,
maxAttempts: FETCH_INSTANCE_MAX_ATTEMPTS,
delayMs: FETCH_INSTANCE_RETRY_DELAY_MS,
});

Expand Down

0 comments on commit 77dcce3

Please sign in to comment.