Skip to content

Commit

Permalink
move Promise.race logic in diagoriente adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
JeromeBu committed Jan 28, 2025
1 parent be3b491 commit 5ca6204
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,28 @@ describe("DiagorienteAppellationsGateway", () => {
},
parallelCalls * requestMinTime * 10 + 500,
);

it("fallsback to empty array when duration is over maximum", async () => {
const config = AppConfig.createFromEnv();
const maxDurationMs = 100;
const appellationsGatewayWithLowMaxDuration =
new DiagorienteAppellationsGateway(
createFetchSharedClient(diagorienteAppellationsRoutes, fetch),
cachingGateway,
{
clientId: config.diagorienteApiClientId,
clientSecret: config.diagorienteApiClientSecret,
},
withNoCache,
maxDurationMs,
);

const appellations =
await appellationsGatewayWithLowMaxDuration.searchAppellations(
"design",
);

expect(appellations).toEqual([]);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Bottleneck from "bottleneck";
import { AppellationDto, appellationCodeSchema } from "shared";
import { AppellationDto, appellationCodeSchema, sleep } from "shared";
import { HttpClient } from "shared-routes";
import { partnerNames } from "../../../../config/bootstrap/partnerNames";
import { createLogger } from "../../../../utils/logger";
import { InMemoryCachingGateway } from "../../caching-gateway/adapters/InMemoryCachingGateway";
import { WithCache } from "../../caching-gateway/port/WithCache";
import { AppellationsGateway } from "../ports/AppellationsGateway";
Expand All @@ -20,6 +22,8 @@ export const requestMinTime = Math.floor(
ONE_SECOND_MS / diagorienteMaxCallRatePerSeconds,
);

const logger = createLogger(__filename);

export class DiagorienteAppellationsGateway implements AppellationsGateway {
#limiter = new Bottleneck({
reservoir: diagorienteMaxCallRatePerSeconds,
Expand All @@ -30,6 +34,7 @@ export class DiagorienteAppellationsGateway implements AppellationsGateway {
});

#withCache: WithCache;
#maxQueryDurationMs: number;

constructor(
private readonly httpClient: HttpClient<DiagorienteAppellationsRoutes>,
Expand All @@ -39,8 +44,10 @@ export class DiagorienteAppellationsGateway implements AppellationsGateway {
clientSecret: string;
},
withCache: WithCache,
maxQueryDurationMs = 700,
) {
this.#withCache = withCache;
this.#maxQueryDurationMs = maxQueryDurationMs;
}

async searchAppellations(rawQuery: string): Promise<AppellationDto[]> {
Expand Down Expand Up @@ -69,7 +76,31 @@ export class DiagorienteAppellationsGateway implements AppellationsGateway {
),
});

return this.#limiter.schedule(() => cachedSearchAppellations(rawQuery));
return this.#limiter.schedule(() => {
const apiCallPromise = cachedSearchAppellations(rawQuery);

return Promise.race([
apiCallPromise,
sleep(this.#maxQueryDurationMs).then(() => {
logger.warn({
partnerApiCall: {
partnerName: partnerNames.diagoriente,
durationInMs: this.#maxQueryDurationMs,
route: diagorienteAppellationsRoutes.searchAppellations,
response: {
kind: "failure",
status: 504,
body: {
message: `Timeout on immersion facilitée side - more than ${this.#maxQueryDurationMs} ms to response`,
},
},
},
});

return [];
}),
]);
});
}

public getAccessToken(): Promise<DiagorienteAccessTokenResponse> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { AppellationDto, sleep, toLowerCaseWithoutDiacritics } from "shared";
import { AppellationDto, toLowerCaseWithoutDiacritics } from "shared";
import { AppellationsGateway } from "../ports/AppellationsGateway";

export class InMemoryAppellationsGateway implements AppellationsGateway {
public async searchAppellations(query: string): Promise<AppellationDto[]> {
if (this.#delayInMs > 0) await sleep(this.#delayInMs);

return this.#nextResults.filter((appellation) =>
toLowerCaseWithoutDiacritics(appellation.appellationLabel).includes(
toLowerCaseWithoutDiacritics(query),
Expand All @@ -16,11 +14,5 @@ export class InMemoryAppellationsGateway implements AppellationsGateway {
this.#nextResults = nextResult;
}

public setDelayInMs(delayInMs: number) {
this.#delayInMs = delayInMs;
}

#delayInMs = 0;

#nextResults: AppellationDto[] = [];
}

This file was deleted.

31 changes: 2 additions & 29 deletions back/src/domains/core/rome/use-cases/AppellationSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@ import {
AppellationAndRomeDto,
AppellationMatchDto,
ROME_AND_APPELLATION_MIN_SEARCH_TEXT_LENGTH,
sleep,
zStringMinLength1,
} from "shared";
import { z } from "zod";
import { partnerNames } from "../../../../config/bootstrap/partnerNames";
import { createLogger } from "../../../../utils/logger";
import { findMatchRanges } from "../../../../utils/textSearch";
import { TransactionalUseCase } from "../../UseCase";
import { UnitOfWork } from "../../unit-of-work/ports/UnitOfWork";
import { UnitOfWorkPerformer } from "../../unit-of-work/ports/UnitOfWorkPerformer";
import { diagorienteAppellationsRoutes } from "../adapters/DiagorienteAppellationsGateway.routes";
import { AppellationsGateway } from "../ports/AppellationsGateway";

const logger = createLogger(__filename);
Expand Down Expand Up @@ -80,32 +77,8 @@ export class AppellationSearch extends TransactionalUseCase<
uow: UnitOfWork,
searchText: string,
): Promise<AppellationAndRomeDto[]> {
const apiCallPromise =
this.#appellationsGateway.searchAppellations(searchText);

const maxDurationMs = 700;

const appellations = await Promise.race([
apiCallPromise,
sleep(maxDurationMs).then(() => {
logger.warn({
partnerApiCall: {
partnerName: partnerNames.diagoriente,
durationInMs: maxDurationMs,
route: diagorienteAppellationsRoutes.searchAppellations,
response: {
kind: "failure",
status: 504,
body: {
message: `Timeout on immersion facilitée side - more than ${maxDurationMs} ms to response`,
},
},
},
});

return [];
}),
]);
const appellations =
await this.#appellationsGateway.searchAppellations(searchText);

if (appellations.length === 0) return [];

Expand Down

0 comments on commit 5ca6204

Please sign in to comment.