-
Notifications
You must be signed in to change notification settings - Fork 14
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 #837 from digirati-co-uk/feature/cache-project
Cache project
- Loading branch information
Showing
13 changed files
with
166 additions
and
15 deletions.
There are no files selected for viewing
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
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,45 @@ | ||
import { RouteMiddleware } from '../types/route-middleware'; | ||
|
||
export type SlowRequests = Record< | ||
string, | ||
{ | ||
key: string; | ||
count: number; | ||
avg: number; | ||
slowest: number; | ||
} | ||
>; | ||
|
||
const slowRequestStore: SlowRequests = {}; | ||
|
||
export const slowRequests: RouteMiddleware<{ slug: string }> = async (context, next) => { | ||
const requestStart = Date.now(); | ||
await next(); | ||
|
||
const routeKey = `${context.method} ${context._matchedRoute}`; | ||
|
||
const requestEnd = Date.now(); | ||
const requestTime = requestEnd - requestStart; | ||
if (!slowRequestStore[routeKey]) { | ||
slowRequestStore[routeKey] = { key: routeKey, count: 0, avg: 0, slowest: 0 }; | ||
} | ||
|
||
const existinRoute = slowRequestStore[routeKey]; | ||
|
||
existinRoute.count++; | ||
existinRoute.avg = (existinRoute.avg * (existinRoute.count - 1) + requestTime) / existinRoute.count; | ||
existinRoute.slowest = Math.max(existinRoute.slowest, requestTime); | ||
|
||
if (Object.keys(slowRequestStore).length > 50) { | ||
// Sort by slowest. | ||
const sorted = Object.values(slowRequestStore).sort((a, b) => b.slowest - a.slowest); | ||
const slowest = sorted.pop(); | ||
if (slowest && slowest.key) { | ||
delete slowRequestStore[slowest.key]; | ||
} | ||
} | ||
}; | ||
|
||
export function getSlowRequests() { | ||
return slowRequestStore; | ||
} |
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,52 @@ | ||
import cache from 'memory-cache'; | ||
|
||
export async function cachePromise<T extends object>( | ||
key: string, | ||
getter: () => Promise<T>, | ||
timeInMs: number | ||
): Promise<T> { | ||
const resource = cache.get(key); | ||
if (resource) { | ||
return resource as T; | ||
} | ||
|
||
const result = await getter(); | ||
cache.put(key, result, timeInMs); | ||
return result; | ||
} | ||
|
||
const swcPromises: Record<string, Promise<any> | null> = {}; | ||
const DEFAULT_STALE_TIME = 1000 * 60 * 60 * 8; // 8 hours | ||
|
||
export async function cachePromiseSWR<T extends object | null>( | ||
key: string, | ||
getter: () => Promise<T>, | ||
timeInMs: number, | ||
staleTimeInMs: number = DEFAULT_STALE_TIME | ||
): Promise<T> { | ||
if (swcPromises[key]) { | ||
await swcPromises[key]; | ||
} | ||
const resource = cache.get(key); | ||
const staleResource = cache.get(`@stale/${key}`); | ||
if (!resource) { | ||
const promise = getter(); | ||
swcPromises[key] = promise; | ||
promise.then(result => { | ||
cache.put(key, result, timeInMs); | ||
cache.put(`@stale/${key}`, result, staleTimeInMs); | ||
|
||
delete swcPromises[key]; | ||
|
||
return result; | ||
}); | ||
|
||
if (staleResource) { | ||
return staleResource; | ||
} | ||
|
||
return promise; | ||
} | ||
|
||
return resource; | ||
} |