Skip to content
Snippets Groups Projects
Commit 75b85eb0 authored by Rhys Arkins's avatar Rhys Arkins
Browse files

refactor: http cache

parent 6c38eb35
No related branches found
No related tags found
No related merge requests found
import crypto from 'crypto'; import crypto from 'crypto';
import URL from 'url'; import URL from 'url';
import { GotPromise } from 'got';
import * as runCache from '../cache/run'; import * as runCache from '../cache/run';
import { clone } from '../clone'; import { clone } from '../clone';
import got from '../got'; import got from '../got';
...@@ -34,10 +33,7 @@ export interface HttpResponse<T = string> { ...@@ -34,10 +33,7 @@ export interface HttpResponse<T = string> {
headers: any; headers: any;
} }
async function cloneResponse<T>( function cloneResponse<T>(response: any): HttpResponse<T> {
promisedResponse: GotPromise<any>
): Promise<HttpResponse<T>> {
const response = await promisedResponse;
// clone body and headers so that the cached result doesn't get accidentally mutated // clone body and headers so that the cached result doesn't get accidentally mutated
return { return {
body: clone<T>(response.body), body: clone<T>(response.body),
...@@ -48,7 +44,7 @@ async function cloneResponse<T>( ...@@ -48,7 +44,7 @@ async function cloneResponse<T>(
export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> { export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> {
constructor(private hostType: string, private options?: HttpOptions) {} constructor(private hostType: string, private options?: HttpOptions) {}
protected request<T>( protected async request<T>(
requestUrl: string | URL, requestUrl: string | URL,
httpOptions?: InternalHttpOptions httpOptions?: InternalHttpOptions
): Promise<HttpResponse<T> | null> { ): Promise<HttpResponse<T> | null> {
...@@ -94,24 +90,24 @@ export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> { ...@@ -94,24 +90,24 @@ export class Http<GetOptions = HttpOptions, PostOptions = HttpPostOptions> {
options = applyAuthorization(options); options = applyAuthorization(options);
// Cache GET requests unless useCache=false // Cache GET requests unless useCache=false
let promisedRes: GotPromise<any>;
if (options.method === 'get') {
const cacheKey = crypto const cacheKey = crypto
.createHash('md5') .createHash('md5')
.update('got-' + JSON.stringify({ url, headers: options.headers })) .update('got-' + JSON.stringify({ url, headers: options.headers }))
.digest('hex'); .digest('hex');
if (options.useCache !== false) { if (options.method === 'get' && options.useCache !== false) {
// check cache unless bypassing it // return from cache if present
promisedRes = runCache.get(cacheKey); const cachedRes = runCache.get(cacheKey);
// istanbul ignore if
if (cachedRes) {
return cloneResponse<T>(await cachedRes);
} }
if (promisedRes === undefined) {
// cache miss OR cache bypass
promisedRes = got(url, options);
} }
runCache.set(cacheKey, promisedRes); // always set const promisedRes = got(url, options);
return cloneResponse<T>(promisedRes); if (options.method === 'get') {
runCache.set(cacheKey, promisedRes); // always set if it's a get
} }
return cloneResponse<T>(got(url, options)); const res = await promisedRes;
return cloneResponse<T>(res);
} }
get(url: string, options: HttpOptions = {}): Promise<HttpResponse> { get(url: string, options: HttpOptions = {}): Promise<HttpResponse> {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment