Merge branch 'cache' into 'main'

Cache

See merge request v3/service/matcher!12
This commit is contained in:
Sylvain Briat 2023-09-29 08:53:55 +00:00
commit cfa7b08ca0
6 changed files with 49 additions and 9 deletions

View File

@ -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).

12
package-lock.json generated
View File

@ -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",
@ -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"

View File

@ -1,6 +1,6 @@
{
"name": "@mobicoop/matcher",
"version": "1.0.0",
"version": "1.1.0",
"description": "Mobicoop V3 Matcher",
"author": "sbriat",
"private": true,
@ -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",

View File

@ -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<RedisClientOptions>({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
store: await redisStore({
host: configService.get<string>('REDIS_HOST'),
port: configService.get<number>('REDIS_PORT'),
password: configService.get<string>('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,

View File

@ -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<MatchingPaginatedResponseDto> {
try {

View File

@ -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();