Browse Source

Merge pull request #136 from sutcalag/main

add cache example
ryjiang 4 years ago
parent
commit
9cdec58a6c

+ 3 - 1
server/package.json

@@ -32,6 +32,7 @@
     "@types/passport-local": "^1.0.33",
     "@types/passport-local": "^1.0.33",
     "@zilliz/milvus2-sdk-node": "^1.0.3",
     "@zilliz/milvus2-sdk-node": "^1.0.3",
     "body-parser": "^1.19.0",
     "body-parser": "^1.19.0",
+    "cache-manager": "^3.4.4",
     "class-transformer": "^0.4.0",
     "class-transformer": "^0.4.0",
     "class-validator": "^0.13.1",
     "class-validator": "^0.13.1",
     "passport": "^0.4.1",
     "passport": "^0.4.1",
@@ -46,6 +47,7 @@
     "@nestjs/cli": "^7.6.0",
     "@nestjs/cli": "^7.6.0",
     "@nestjs/schematics": "^7.3.0",
     "@nestjs/schematics": "^7.3.0",
     "@nestjs/testing": "^7.6.15",
     "@nestjs/testing": "^7.6.15",
+    "@types/cache-manager": "^3.4.2",
     "@types/express": "^4.17.11",
     "@types/express": "^4.17.11",
     "@types/jest": "^26.0.22",
     "@types/jest": "^26.0.22",
     "@types/node": "^14.14.36",
     "@types/node": "^14.14.36",
@@ -82,4 +84,4 @@
     "coverageDirectory": "../coverage",
     "coverageDirectory": "../coverage",
     "testEnvironment": "node"
     "testEnvironment": "node"
   }
   }
-}
+}

+ 5 - 0
server/src/cache/config.ts

@@ -0,0 +1,5 @@
+export const ttl = 10; //seconds
+export const cacheKeys = {
+  LOADEDCOLLECTIONS: 'LOADEDCOLLECTIONS',
+  ALLCOLLECTIONS: 'ALLCOLLECTIONS',
+};

+ 32 - 4
server/src/collections/collections.controller.ts

@@ -9,7 +9,12 @@ import {
   Query,
   Query,
   UsePipes,
   UsePipes,
   ValidationPipe,
   ValidationPipe,
+  CACHE_MANAGER,
+  Inject,
+  UseInterceptors,
+  CacheInterceptor,
 } from '@nestjs/common';
 } from '@nestjs/common';
+import { Cache } from 'cache-manager';
 import { ApiTags } from '@nestjs/swagger';
 import { ApiTags } from '@nestjs/swagger';
 import { CollectionsService } from './collections.service';
 import { CollectionsService } from './collections.service';
 import {
 import {
@@ -18,20 +23,38 @@ import {
   ShowCollections,
   ShowCollections,
   VectorSearch,
   VectorSearch,
 } from './dto';
 } from './dto';
+import { cacheKeys } from '../cache/config';
 
 
+//Including 2 kind of cache check getCollections and getStatistics for detail
 @ApiTags('collections')
 @ApiTags('collections')
 @Controller('collections')
 @Controller('collections')
 export class CollectionsController {
 export class CollectionsController {
-  constructor(private collectionsService: CollectionsService) {}
+  constructor(private collectionsService: CollectionsService, @Inject(CACHE_MANAGER) private cacheManager: Cache) { }
 
 
+  // manually control cache if logic is complicated
   @Get()
   @Get()
   async getCollections(@Query() data?: ShowCollections) {
   async getCollections(@Query() data?: ShowCollections) {
-    return Number(data.type) === 1
-      ? await this.collectionsService.getLoadedColletions()
-      : await this.collectionsService.getAllCollections();
+    if (Number(data.type) === 1) {
+      let loadedCollections = await this.cacheManager.get(cacheKeys.LOADEDCOLLECTIONS);
+      if (loadedCollections) {
+        return loadedCollections;
+      }
+      loadedCollections = await this.collectionsService.getLoadedColletions();
+      await this.cacheManager.set(cacheKeys.LOADEDCOLLECTIONS, loadedCollections);
+      return loadedCollections;
+    }
+    let allCollections = await this.cacheManager.get(cacheKeys.ALLCOLLECTIONS);
+    if (allCollections) {
+      return allCollections;
+    }
+    allCollections = await this.collectionsService.getAllCollections();
+    await this.cacheManager.set(cacheKeys.ALLCOLLECTIONS, allCollections);
+    return allCollections;
   }
   }
 
 
+  // use interceptor to control cache automatically
   @Get('statistics')
   @Get('statistics')
+  @UseInterceptors(CacheInterceptor)
   async getStatistics() {
   async getStatistics() {
     return await this.collectionsService.getStatistics();
     return await this.collectionsService.getStatistics();
   }
   }
@@ -39,12 +62,14 @@ export class CollectionsController {
   @Post()
   @Post()
   @UsePipes(new ValidationPipe())
   @UsePipes(new ValidationPipe())
   async createCollection(@Body() data: CreateCollection) {
   async createCollection(@Body() data: CreateCollection) {
+    await this.cacheManager.del(cacheKeys.ALLCOLLECTIONS);
     return await this.collectionsService.createCollection(data);
     return await this.collectionsService.createCollection(data);
   }
   }
 
 
   @Delete(':name')
   @Delete(':name')
   // todo: need check some special symbols
   // todo: need check some special symbols
   async deleteCollection(@Param('name') name: string) {
   async deleteCollection(@Param('name') name: string) {
+    await this.cacheManager.del(cacheKeys.ALLCOLLECTIONS);
     return await this.collectionsService.dropCollection({
     return await this.collectionsService.dropCollection({
       collection_name: name,
       collection_name: name,
     });
     });
@@ -71,6 +96,7 @@ export class CollectionsController {
 
 
   @Put(':name/load')
   @Put(':name/load')
   async loadCollection(@Param('name') name: string) {
   async loadCollection(@Param('name') name: string) {
+    await this.cacheManager.del(cacheKeys.LOADEDCOLLECTIONS);
     return await this.collectionsService.loadCollection({
     return await this.collectionsService.loadCollection({
       collection_name: name,
       collection_name: name,
     });
     });
@@ -78,6 +104,7 @@ export class CollectionsController {
 
 
   @Put(':name/release')
   @Put(':name/release')
   async releaseCollection(@Param('name') name: string) {
   async releaseCollection(@Param('name') name: string) {
+    await this.cacheManager.del(cacheKeys.LOADEDCOLLECTIONS);
     return await this.collectionsService.releaseCollection({
     return await this.collectionsService.releaseCollection({
       collection_name: name,
       collection_name: name,
     });
     });
@@ -85,6 +112,7 @@ export class CollectionsController {
 
 
   @Post(':name/insert')
   @Post(':name/insert')
   async insertData(@Param('name') name: string, @Body() data: InsertData) {
   async insertData(@Param('name') name: string, @Body() data: InsertData) {
+    await this.cacheManager.del(cacheKeys.ALLCOLLECTIONS);
     return await this.collectionsService.insert({
     return await this.collectionsService.insert({
       collection_name: name,
       collection_name: name,
       ...data,
       ...data,

+ 9 - 3
server/src/collections/collections.module.ts

@@ -1,11 +1,17 @@
-import { Module } from '@nestjs/common';
+import { Module, CacheModule } from '@nestjs/common';
 import { CollectionsService } from './collections.service';
 import { CollectionsService } from './collections.service';
 import { CollectionsController } from './collections.controller';
 import { CollectionsController } from './collections.controller';
 import { MilvusModule } from '../milvus/milvus.module';
 import { MilvusModule } from '../milvus/milvus.module';
+import { ttl } from '../cache/config';
 
 
 @Module({
 @Module({
-  imports: [MilvusModule],
+  imports: [
+    MilvusModule,
+    CacheModule.register({
+      ttl, // seconds
+    }),
+  ],
   providers: [CollectionsService],
   providers: [CollectionsService],
   controllers: [CollectionsController],
   controllers: [CollectionsController],
 })
 })
-export class CollectionsModule {}
+export class CollectionsModule { }

+ 20 - 1
server/yarn.lock

@@ -848,6 +848,11 @@
     "@types/connect" "*"
     "@types/connect" "*"
     "@types/node" "*"
     "@types/node" "*"
 
 
+"@types/cache-manager@^3.4.2":
+  version "3.4.2"
+  resolved "https://registry.yarnpkg.com/@types/cache-manager/-/cache-manager-3.4.2.tgz#d57e7e5e6374d1037bdce753a05c9703e4483401"
+  integrity sha512-1IwA74t5ID4KWo0Kndal16MhiPSZgMe1fGc+MLT6j5r+Ab7jku36PFTl4PP6MiWw0BJscM9QpZEo00qixNQoRg==
+
 "@types/connect@*":
 "@types/connect@*":
   version "3.4.34"
   version "3.4.34"
   resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901"
   resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901"
@@ -1483,6 +1488,11 @@ astral-regex@^2.0.0:
   resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
   resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
   integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
   integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
 
 
+async@3.2.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
+  integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
+
 asynckit@^0.4.0:
 asynckit@^0.4.0:
   version "0.4.0"
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -1731,6 +1741,15 @@ cache-base@^1.0.1:
     union-value "^1.0.0"
     union-value "^1.0.0"
     unset-value "^1.0.0"
     unset-value "^1.0.0"
 
 
+cache-manager@^3.4.4:
+  version "3.4.4"
+  resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-3.4.4.tgz#c69814763d3f3031395ae0d3a9a9296a91602226"
+  integrity sha512-oayy7ukJqNlRUYNUfQBwGOLilL0X5q7GpuaF19Yqwo6qdx49OoTZKRIF5qbbr+Ru8mlTvOpvnMvVq6vw72pOPg==
+  dependencies:
+    async "3.2.0"
+    lodash "^4.17.21"
+    lru-cache "6.0.0"
+
 call-bind@^1.0.0:
 call-bind@^1.0.0:
   version "1.0.2"
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
   resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
@@ -4096,7 +4115,7 @@ long@^4.0.0:
   resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
   resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
   integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
   integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
 
 
-lru-cache@^6.0.0:
+lru-cache@6.0.0, lru-cache@^6.0.0:
   version "6.0.0"
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
   integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
   integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==