-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #419 from magieno/try-to-improve-speed-using-contr…
…oller-caching Try to improve speed using controller caching
- Loading branch information
Showing
21 changed files
with
637 additions
and
510 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import {Request} from "../models/request"; | ||
import {RequestUtil} from "./request.util"; | ||
import {HttpMethod} from "../enums/http-method.enum"; | ||
|
||
describe("Request Util", () => { | ||
it("should hash the same request twice", () => { | ||
const rawBody = {}; | ||
|
||
const request: Request = new Request(HttpMethod.Get, "http://www.subdomain.ima-tech.ca/api/1.0/dogs/caniche-royal?query=searchTerm&sort=ASC#anchorLink"); | ||
request.rawBody = rawBody; | ||
request.setHeaders({ | ||
"header1": "value1", | ||
"header2": "value2", | ||
"header3": "value3", | ||
}); | ||
|
||
const request2: Request = new Request(HttpMethod.Get, "http://www.subdomain.ima-tech.ca/api/1.0/dogs/caniche-royal?sort=ASC&query=searchTerm#anchorLink");; | ||
request2.rawBody = rawBody; | ||
request2.setHeaders({ | ||
"header3": "value3", | ||
"header2": "value2", | ||
"header1": "value1", | ||
}); | ||
|
||
const request1Hash = RequestUtil.hash(request); | ||
const request2Hash = RequestUtil.hash(request2); | ||
|
||
expect(request1Hash).toBe(request2Hash); | ||
}) | ||
|
||
it("should not hash different requests to the same value", () => { | ||
const rawBody = {}; | ||
|
||
const request: Request = new Request(HttpMethod.Get, "http://www.subdomain.ima-tech.ca/api/1.0/dogs/caniche-royal?query=searchTerm&sort=ASC#anchorLink"); | ||
request.rawBody = rawBody; | ||
request.setHeaders({ | ||
"header1": "value1", | ||
"header2": "value2", | ||
"header3": "value3", | ||
}); | ||
|
||
const request2: Request = new Request(HttpMethod.Get, "http://www.subdomain.ima-tech.ca/api/1.0/dogs/caniche-royal?sort=ASC&query=searchTermXXXXX#anchorLink");; | ||
request2.rawBody = rawBody; | ||
request2.setHeaders({ | ||
"header3": "value3", | ||
"header2": "value2", | ||
"header1": "value1", | ||
}); | ||
|
||
const request3: Request = new Request(HttpMethod.Get, "http://www.subdomain.ima-tech.ca/api/1.0/dogs/caniche-royal?sort=ASC&query=searchTerm"); | ||
request2.rawBody = rawBody; | ||
request2.setHeaders({ | ||
"header3": "value3", | ||
"header2": "value2", | ||
"header1": "value1", | ||
}); | ||
|
||
const request1Hash = RequestUtil.hash(request); | ||
const request2Hash = RequestUtil.hash(request2); | ||
const request3Hash = RequestUtil.hash(request3); | ||
|
||
expect(request1Hash).not.toBe(request2Hash); | ||
expect(request1Hash).not.toBe(request3Hash); | ||
expect(request2Hash).not.toBe(request3Hash); | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { createHash } from 'crypto'; | ||
import {Request} from "../models/request"; | ||
import { URL } from 'url'; | ||
|
||
function sort(obj: any) { | ||
const ret: any = {}; | ||
|
||
Object.keys(obj).sort().forEach(function (key) { | ||
ret[key] = obj[key]; | ||
}); | ||
|
||
return ret; | ||
} | ||
|
||
export class RequestUtil { | ||
static hash(request: Request): string | null { | ||
const hash = createHash("md5"); | ||
|
||
const parsedUrl = new URL(request.url); | ||
|
||
parsedUrl.searchParams.sort(); | ||
|
||
hash.update(parsedUrl.pathname); | ||
hash.update(request.httpMethod); | ||
hash.update(parsedUrl.searchParams.toString()); | ||
hash.update(parsedUrl.hash); | ||
hash.update(JSON.stringify(sort(request.headers))); | ||
|
||
try { | ||
hash.write(JSON.stringify(request.body)); | ||
} catch (e) { | ||
return null; | ||
} | ||
|
||
|
||
return hash.digest("hex"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./request.util"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./cached.router-route"; | ||
export * from "./router.cache"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import {MethodRouterNode} from "../nodes/method-router.node"; | ||
import {Request, RequestUtil} from "@pristine-ts/common"; | ||
|
||
export class CachedRouterRoute { | ||
private cachedControllerMethodArguments: { [requestHash: string]: any[] } = {}; | ||
public routeParameters?: { [key: string]: string }; | ||
|
||
constructor(public readonly methodNode: MethodRouterNode, | ||
) { | ||
} | ||
|
||
private hashRequest(request: Request): string | null { | ||
return RequestUtil.hash(request); | ||
} | ||
|
||
getCachedControllerMethodArguments(request: Request): any[] | undefined { | ||
// Hashed the request | ||
const hash = this.hashRequest(request); | ||
|
||
if(hash === null) { | ||
return; | ||
} | ||
|
||
// Return the arguments if the hashed request exists | ||
return this.cachedControllerMethodArguments[hash]; | ||
} | ||
|
||
cacheControllerMethodArguments(request: Request, methodArguments: any[]): void { | ||
// Hashed the request | ||
const hash = this.hashRequest(request); | ||
|
||
if(hash === null) { | ||
return; | ||
} | ||
|
||
// Save the method arguments | ||
this.cachedControllerMethodArguments[hash] = methodArguments; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import {Request, tag} from "@pristine-ts/common"; | ||
import {singleton, injectable, inject} from "tsyringe"; | ||
import {CachedRouterRoute} from "./cached.router-route"; | ||
import {MethodRouterNode} from "../nodes/method-router.node"; | ||
import {NetworkingModuleKeyname} from "../networking.module.keyname"; | ||
|
||
@injectable() | ||
export class RouterCache { | ||
public routes: {[methodAndPath: string] : CachedRouterRoute} = {}; | ||
|
||
public constructor(@inject(`%${NetworkingModuleKeyname}.routerCache.isActive%`) private readonly isActive: boolean) { | ||
} | ||
|
||
private cleanIfNeeded() { | ||
// todo: implement a proper LRU cache and also, remove the two layers of cache and flatten it to one. | ||
} | ||
|
||
public get(keyname: string): CachedRouterRoute | undefined { | ||
if(this.isActive === false) { | ||
return undefined; | ||
} | ||
|
||
return this.routes[keyname]; | ||
} | ||
|
||
public set(keyname: string, methodNode: MethodRouterNode): CachedRouterRoute { | ||
const cachedRouterRoute = new CachedRouterRoute(methodNode); | ||
|
||
if(this.isActive === false) { | ||
return cachedRouterRoute; | ||
} | ||
|
||
// todo Calculate the size and add it to the current total | ||
|
||
// Whenever we add a new element to the cache, we have to check if the cache needs to be cleaned | ||
this.cleanIfNeeded(); | ||
|
||
this.routes[keyname] = cachedRouterRoute; | ||
|
||
return cachedRouterRoute; | ||
} | ||
|
||
public getCachedControllerMethodArguments(keyname: string, request: Request): any[] | undefined { | ||
if(this.isActive === false) { | ||
return undefined; | ||
} | ||
|
||
return this.routes[keyname]?.getCachedControllerMethodArguments(request); | ||
} | ||
|
||
public setControllerMethodArguments(keyname: string, request: Request, methodArguments: any[]) { | ||
if(this.isActive === false) { | ||
return; | ||
} | ||
|
||
this.routes[keyname]?.cacheControllerMethodArguments(request, methodArguments); | ||
|
||
return; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.