From bd18e4543bf5c6d7233f45fbb0099e17590bef8c Mon Sep 17 00:00:00 2001 From: sbriat Date: Fri, 29 Sep 2023 10:45:23 +0200 Subject: [PATCH 1/2] use basic cache --- README.md | 9 ++++++++ package-lock.json | 8 ++++--- package.json | 2 +- src/modules/ad/ad.module.ts | 23 ++++++++++++++++++- .../grpc-controllers/match.grpc-controller.ts | 5 +++- .../interface/match.grpc.controller.spec.ts | 5 ++++ 6 files changed, 46 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7d655f8..171ee81 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,15 @@ If the matching is successful, you will get a result, containing : - _INTERMEDIATE_ for a driver intermediate point - _NEUTRAL_ for a passenger point from the point of view of a driver +### Results caching + +Matching is a time-consuming process, so the results of a matching request are stored in cache before being paginated and returned to the requester. +An id is attributed to the overall results of a request : on further requests (for example to query for different pages of results), the requester can provide this id and get in return the cached data, avoiding another longer process of computing the results from scratch. Obviously, new computing must be done periodically to get fresh new results ! + +There's also a basic cache to store the results of the _same_ request sent multiple times successively. + +Cache TTLs are customizable in the `.env` file. + ## Tests / ESLint / Prettier Tests are run outside the container for ease of use (switching between different environments inside containers using prisma is complicated and error prone). diff --git a/package-lock.json b/package-lock.json index ce905e2..c8682bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@nestjs/terminus": "^9.2.2", "@prisma/client": "^4.13.0", "axios": "^1.3.5", - "cache-manager": "^5.2.0", + "cache-manager": "^5.2.3", "cache-manager-ioredis-yet": "^1.1.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", @@ -1584,7 +1584,8 @@ }, "node_modules/@nestjs/cache-manager": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-1.0.0.tgz", + "integrity": "sha512-XMNdgsj3H+Ng/SYwFl13vRGNFA3e5Obk8LNwIuHLVSocnK2exReAWtscxEjQhoBc4FW4jAYOgU/U+mt18Q9T0g==", "peerDependencies": { "@nestjs/common": "^9.0.0", "cache-manager": "<=5", @@ -3385,7 +3386,8 @@ }, "node_modules/cache-manager": { "version": "5.2.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.2.3.tgz", + "integrity": "sha512-9OErI8fksFkxAMJ8Mco0aiZSdphyd90HcKiOMJQncSlU1yq/9lHHxrT8PDayxrmr9IIIZPOAEfXuGSD7g29uog==", "dependencies": { "lodash.clonedeep": "^4.5.0", "lru-cache": "^9.1.2" diff --git a/package.json b/package.json index 32d120f..0e8aa84 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@nestjs/terminus": "^9.2.2", "@prisma/client": "^4.13.0", "axios": "^1.3.5", - "cache-manager": "^5.2.0", + "cache-manager": "^5.2.3", "cache-manager-ioredis-yet": "^1.1.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index 3756e70..93a9072 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -35,6 +35,27 @@ import { MatchMapper } from './match.mapper'; import { OutputDateTimeTransformer } from './infrastructure/output-datetime-transformer'; import { MatchingRepository } from './infrastructure/matching.repository'; import { MatchingMapper } from './matching.mapper'; +import { CacheModule } from '@nestjs/cache-manager'; +import { RedisClientOptions } from '@liaoliaots/nestjs-redis'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { redisStore } from 'cache-manager-ioredis-yet'; + +const imports = [ + CqrsModule, + CacheModule.registerAsync({ + imports: [ConfigModule], + useFactory: async (configService: ConfigService) => ({ + store: await redisStore({ + host: configService.get('REDIS_HOST'), + port: configService.get('REDIS_PORT'), + password: configService.get('REDIS_PASSWORD'), + ttl: configService.get('CACHE_TTL'), + }), + }), + inject: [ConfigService], + }), + GeographyModule, +]; const grpcControllers = [MatchGrpcController]; @@ -106,7 +127,7 @@ const adapters: Provider[] = [ ]; @Module({ - imports: [CqrsModule, GeographyModule], + imports, controllers: [...grpcControllers], providers: [ ...messageHandlers, diff --git a/src/modules/ad/interface/grpc-controllers/match.grpc-controller.ts b/src/modules/ad/interface/grpc-controllers/match.grpc-controller.ts index 930eaa9..a6bf5af 100644 --- a/src/modules/ad/interface/grpc-controllers/match.grpc-controller.ts +++ b/src/modules/ad/interface/grpc-controllers/match.grpc-controller.ts @@ -1,4 +1,4 @@ -import { Controller, Inject, UsePipes } from '@nestjs/common'; +import { Controller, Inject, UseInterceptors, UsePipes } from '@nestjs/common'; import { GrpcMethod, RpcException } from '@nestjs/microservices'; import { RpcValidationPipe } from '@mobicoop/ddd-library'; import { RpcExceptionCode } from '@mobicoop/ddd-library'; @@ -11,6 +11,7 @@ import { AD_ROUTE_PROVIDER } from '@modules/ad/ad.di-tokens'; import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port'; import { MatchMapper } from '@modules/ad/match.mapper'; import { MatchingResult } from '@modules/ad/core/application/queries/match/match.query-handler'; +import { CacheInterceptor, CacheKey } from '@nestjs/cache-manager'; @UsePipes( new RpcValidationPipe({ @@ -27,6 +28,8 @@ export class MatchGrpcController { private readonly matchMapper: MatchMapper, ) {} + @CacheKey('MatcherServiceMatch') + @UseInterceptors(CacheInterceptor) @GrpcMethod('MatcherService', 'Match') async match(data: MatchRequestDto): Promise { try { diff --git a/src/modules/ad/tests/unit/interface/match.grpc.controller.spec.ts b/src/modules/ad/tests/unit/interface/match.grpc.controller.spec.ts index a138f04..7739a25 100644 --- a/src/modules/ad/tests/unit/interface/match.grpc.controller.spec.ts +++ b/src/modules/ad/tests/unit/interface/match.grpc.controller.spec.ts @@ -13,6 +13,7 @@ import { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/mat import { WaypointDto } from '@modules/ad/interface/grpc-controllers/dtos/waypoint.dto'; import { MatchGrpcController } from '@modules/ad/interface/grpc-controllers/match.grpc-controller'; import { MatchMapper } from '@modules/ad/match.mapper'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; import { QueryBus } from '@nestjs/cqrs'; import { RpcException } from '@nestjs/microservices'; import { Test, TestingModule } from '@nestjs/testing'; @@ -316,6 +317,10 @@ describe('Match Grpc Controller', () => { provide: MatchMapper, useValue: mockMatchMapper, }, + { + provide: CACHE_MANAGER, + useValue: {}, + }, ], }).compile(); From 5e1ebbb61bac22d9cd6d145fa405df12c4ac00c8 Mon Sep 17 00:00:00 2001 From: sbriat Date: Fri, 29 Sep 2023 10:45:29 +0200 Subject: [PATCH 2/2] 1.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c8682bc..34f1db0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mobicoop/matcher", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mobicoop/matcher", - "version": "1.0.0", + "version": "1.1.0", "license": "AGPL", "dependencies": { "@grpc/grpc-js": "^1.8.14", diff --git a/package.json b/package.json index 0e8aa84..b9f4a6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mobicoop/matcher", - "version": "1.0.0", + "version": "1.1.0", "description": "Mobicoop V3 Matcher", "author": "sbriat", "private": true,