From 64464fd04c07134104ec4854cf0581eeef4bf57f Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Fri, 3 Jan 2020 22:24:16 -0800 Subject: [PATCH 1/2] Don't make duplicated requests through Ember Data This will prevent duplicated requests on `/crates` and other Ember Data-powered pages. --- app/adapters/application.js | 15 +++++++++++++++ app/services/fetcher.js | 36 +++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/app/adapters/application.js b/app/adapters/application.js index ab51264c6d6..4e19c99e1c2 100644 --- a/app/adapters/application.js +++ b/app/adapters/application.js @@ -4,9 +4,24 @@ import { inject as service } from '@ember/service'; export default RESTAdapter.extend({ fastboot: service(), + fetcher: service(), namespace: 'api/v1', + ajax(url, type, options) { + if (type === 'GET') { + let cache = this.fetcher.get(url); + if (cache) { + return cache; + } + } + + return this._super(url, type, options).then(resp => { + this.fetcher.put(url, resp); + return resp; + }); + }, + headers: computed('fastboot.{isFastBoot,request.headers}', function () { if (this.fastboot.isFastBoot) { return { 'User-Agent': this.fastboot.request.headers.get('User-Agent') }; diff --git a/app/services/fetcher.js b/app/services/fetcher.js index ca43935318f..4f1f7c4a815 100644 --- a/app/services/fetcher.js +++ b/app/services/fetcher.js @@ -2,26 +2,40 @@ import Service, { inject as service } from '@ember/service'; import ajax from '../utils/ajax'; +const KEY = 'ajax-cache'; + export default class FetcherService extends Service { @service fastboot; - ajax(url) { + get(url) { + let shoebox = this.fastboot.shoebox; + if (!shoebox) { + return; + } + let cache = shoebox.retrieve(KEY) || {}; + return cache[url]; + } + + put(url, obj) { let fastboot = this.fastboot; let shoebox = this.fastboot.shoebox; - let cache = shoebox.retrieve('ajax-cache'); - if (!cache) { - cache = {}; + if (!(shoebox && fastboot.isFastBoot)) { + return; } - if (cache[url]) { - return cache[url]; + let cache = shoebox.retrieve(KEY) || {}; + cache[url] = deepCopy(obj); + shoebox.put(KEY, cache); + } + + ajax(url) { + let resp = this.get(url); + if (resp) { + return resp; } - return ajax(url).then(function (resp) { - if (shoebox && fastboot.isFastBoot) { - cache[url] = deepCopy(resp); - shoebox.put('ajax-cache', cache); - } + return ajax(url).then(resp => { + this.put(url, resp); return resp; }); } From 9578812f9eef64d3fa3665c98ec207f6755166fd Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Tue, 18 Feb 2020 22:43:26 -0800 Subject: [PATCH 2/2] Handle query parameters correctly The options parameter is used to represent query parameters. So it must be included to differentiate URLs with different query parameters. --- app/adapters/application.js | 4 ++-- app/services/fetcher.js | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/adapters/application.js b/app/adapters/application.js index 4e19c99e1c2..dc9c3188d1c 100644 --- a/app/adapters/application.js +++ b/app/adapters/application.js @@ -10,14 +10,14 @@ export default RESTAdapter.extend({ ajax(url, type, options) { if (type === 'GET') { - let cache = this.fetcher.get(url); + let cache = this.fetcher.get(url, options); if (cache) { return cache; } } return this._super(url, type, options).then(resp => { - this.fetcher.put(url, resp); + this.fetcher.put(url, options, resp); return resp; }); }, diff --git a/app/services/fetcher.js b/app/services/fetcher.js index 4f1f7c4a815..5e0940c789f 100644 --- a/app/services/fetcher.js +++ b/app/services/fetcher.js @@ -7,16 +7,17 @@ const KEY = 'ajax-cache'; export default class FetcherService extends Service { @service fastboot; - get(url) { + get(url, options) { let shoebox = this.fastboot.shoebox; if (!shoebox) { return; } let cache = shoebox.retrieve(KEY) || {}; - return cache[url]; + let key = cacheKey(url, options); + return cache[key]; } - put(url, obj) { + put(url, options, obj) { let fastboot = this.fastboot; let shoebox = this.fastboot.shoebox; if (!(shoebox && fastboot.isFastBoot)) { @@ -24,7 +25,8 @@ export default class FetcherService extends Service { } let cache = shoebox.retrieve(KEY) || {}; - cache[url] = deepCopy(obj); + let key = cacheKey(url, options); + cache[key] = deepCopy(obj); shoebox.put(KEY, cache); } @@ -41,6 +43,10 @@ export default class FetcherService extends Service { } } +function cacheKey(url, options) { + return url + JSON.stringify(options); +} + function deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); }