Skip to content

Commit

Permalink
Return already inflight requests for findRecord when CUSTOM_MODEL_CLA…
Browse files Browse the repository at this point in the history
…SS is on
  • Loading branch information
igorT authored Aug 5, 2021
1 parent 4b9d682 commit 804a92e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 9 deletions.
50 changes: 50 additions & 0 deletions packages/-ember-data/tests/integration/store-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,56 @@ module('integration/store - findRecord', function (hooks) {
assert.strictEqual(car.get('model'), 'Princess', 'cached record ignored, record reloaded via server');
});

test('store#findRecord caches the inflight requests', async function (assert) {
assert.expect(2);

let calls = 0;
let resolveHandler;
let result = {
data: {
type: 'car',
id: '1',
attributes: {
make: 'BMC',
model: 'Mini',
},
},
};

const testAdapter = DS.JSONAPIAdapter.extend({
shouldReloadRecord(store, type, id, snapshot) {
assert.ok(false, 'shouldReloadRecord should not be called when { reload: true }');
},
async findRecord() {
calls++;

return new Promise((resolve) => {
resolveHandler = resolve;
});
},
});

this.owner.register('adapter:application', testAdapter);
this.owner.register('serializer:application', JSONAPISerializer.extend());
let firstPromise, secondPromise;

run(() => {
firstPromise = store.findRecord('car', '1');
});

run(() => {
secondPromise = store.findRecord('car', '1');
});

assert.strictEqual(calls, 1, 'We made one call to findRecord');

resolveHandler(result);
let car1 = await firstPromise;
let car2 = await secondPromise;

assert.strictEqual(car1, car2, 'we receive the same car back');
});

test('store#findRecord { backgroundReload: false } returns cached record and does not reload in the background', async function (assert) {
assert.expect(2);

Expand Down
15 changes: 7 additions & 8 deletions packages/store/addon/-private/system/core-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import RecordArrayManager from './record-array-manager';
import { setRecordDataFor } from './record-data-for';
import NotificationManager from './record-notification-manager';
import { RecordReference } from './references';
import { RequestPromise } from './request-cache';
import { _bind, _guard, _objectIsAlive, guardDestroyedStore } from './store/common';
import { _find, _findAll, _findBelongsTo, _findHasMany, _findMany, _query, _queryRecord } from './store/finders';
import { internalModelFactoryFor, recordIdentifierFor, setRecordIdentifier } from './store/internal-model-factory';
Expand Down Expand Up @@ -1268,6 +1267,10 @@ abstract class CoreStore extends Service {
}
} else {
if (internalModel.currentState.isLoading) {
let pending = this._fetchManager.getPendingFetch(internalModel.identifier);
if (pending) {
return pending.then(() => Promise.resolve(internalModel));
}
return this._scheduleFetch(internalModel, options);
}
}
Expand Down Expand Up @@ -2012,13 +2015,9 @@ abstract class CoreStore extends Service {
if (internalModel) {
// short circuit if we are already loading
if (REQUEST_SERVICE) {
// Temporary fix for requests already loading until we move this inside the fetch manager
let pendingRequests = this.getRequestStateService()
.getPendingRequestsForRecord(internalModel.identifier)
.filter((req) => req.type === 'query');

if (pendingRequests.length > 0) {
return pendingRequests[0][RequestPromise].then(() => internalModel.getRecord());
let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier);
if (pendingRequest) {
return pendingRequest.then(() => internalModel.getRecord());
}
} else {
if (internalModel.currentState.isLoading) {
Expand Down
14 changes: 13 additions & 1 deletion packages/store/addon/-private/system/fetch-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import { default as RSVP, Promise } from 'rsvp';
import { symbol } from '../utils/symbol';
import coerceId from './coerce-id';
import { errorsArrayToHash } from './errors-utils';
import RequestCache from './request-cache';
import RequestCache, { RequestPromise } from './request-cache';
import Snapshot from './snapshot';
import { _bind, _guard, _objectIsAlive, guardDestroyedStore } from './store/common';
import { normalizeResponseHelper } from './store/serializer-response';

type StableRecordIdentifier = import('../ts-interfaces/identifier').StableRecordIdentifier;

type CoreStore = import('./core-store').default;
type FindRecordQuery = import('../ts-interfaces/fetch-manager').FindRecordQuery;
type SaveRecordMutation = import('../ts-interfaces/fetch-manager').SaveRecordMutation;
Expand Down Expand Up @@ -507,6 +509,16 @@ export default class FetchManager {
}
}

getPendingFetch(identifier: StableRecordIdentifier) {
let pendingRequests = this.requestCache
.getPendingRequestsForRecord(identifier)
.filter((req) => req.type === 'query');

if (pendingRequests.length > 0) {
return pendingRequests[0][RequestPromise];
}
}

flushAllPendingFetches() {
if (this.isDestroyed) {
return;
Expand Down

0 comments on commit 804a92e

Please sign in to comment.