Skip to content

Commit

Permalink
Use priority queue to run resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Jul 15, 2020
1 parent de352f7 commit dc48adb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
22 changes: 13 additions & 9 deletions packages/data/src/namespace-store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import combineReducers from 'turbo-combine-reducers';
* WordPress dependencies
*/
import createReduxRoutineMiddleware from '@wordpress/redux-routine';
import { createQueue } from '@wordpress/priority-queue';

/**
* Internal dependencies
Expand Down Expand Up @@ -37,6 +38,7 @@ import * as metadataActions from './metadata/actions';
export default function createNamespace( key, options, registry ) {
const reducer = options.reducer;
const store = createReduxStore( key, options, registry );
const resolversQueue = createQueue();

let resolvers;
const actions = mapActions(
Expand Down Expand Up @@ -64,7 +66,12 @@ export default function createNamespace( key, options, registry ) {
store
);
if ( options.resolvers ) {
const result = mapResolvers( options.resolvers, selectors, store );
const result = mapResolvers(
options.resolvers,
selectors,
store,
resolversQueue
);
resolvers = result.resolvers;
selectors = result.selectors;
}
Expand Down Expand Up @@ -166,7 +173,6 @@ function createReduxStore( key, options, registry ) {
* public facing API. Selectors will get passed the
* state as first argument.
* @param {Object} store The store to which the selectors should be mapped.
*
* @return {Object} Selectors mapped to the provided store.
*/
function mapSelectors( selectors, store ) {
Expand Down Expand Up @@ -218,9 +224,10 @@ function mapActions( actions, store ) {
* @param {Object} resolvers Resolvers to register.
* @param {Object} selectors The current selectors to be modified.
* @param {Object} store The redux store to which the resolvers should be mapped.
* @param {Object} queue Resolvers async queue.
* @return {Object} An object containing updated selectors and resolvers.
*/
function mapResolvers( resolvers, selectors, store ) {
function mapResolvers( resolvers, selectors, store, queue ) {
const mappedResolvers = mapValues( resolvers, ( resolver ) => {
const { fulfill: resolverFulfill = resolver } = resolver;
return { ...resolver, fulfill: resolverFulfill };
Expand All @@ -233,7 +240,6 @@ function mapResolvers( resolvers, selectors, store ) {
return selector;
}

let running = false;
const selectorResolver = ( ...args ) => {
async function fulfillSelector() {
const state = store.getState();
Expand All @@ -245,8 +251,8 @@ function mapResolvers( resolvers, selectors, store ) {
}

const { metadata } = store.__unstableOriginalGetState();

if (
running ||
metadataSelectors.hasStartedResolution(
metadata,
selectorName,
Expand All @@ -256,8 +262,7 @@ function mapResolvers( resolvers, selectors, store ) {
return;
}

running = true;
setTimeout( async () => {
queue.add( {}, async () => {
store.dispatch(
metadataActions.startResolution( selectorName, args )
);
Expand All @@ -270,8 +275,7 @@ function mapResolvers( resolvers, selectors, store ) {
store.dispatch(
metadataActions.finishResolution( selectorName, args )
);
running = false;
}, 0 );
} );
}

fulfillSelector( ...args );
Expand Down
13 changes: 13 additions & 0 deletions packages/data/src/namespace-store/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
import { createRegistry } from '../../registry';
import { createRegistryControl } from '../../factory';

// This makes the prioriy queue synchronous to ease unit testing resolvers.
jest.mock( '@wordpress/priority-queue', () => {
return {
createQueue() {
return {
add( ctx, callback ) {
callback();
},
};
},
};
} );

describe( 'controls', () => {
let registry;

Expand Down
13 changes: 13 additions & 0 deletions packages/data/src/test/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ import { castArray, mapValues } from 'lodash';
import { createRegistry } from '../registry';
import { createRegistrySelector } from '../factory';

// This makes the prioriy queue synchronous to ease unit testing resolvers.
jest.mock( '@wordpress/priority-queue', () => {
return {
createQueue() {
return {
add( ctx, callback ) {
callback();
},
};
},
};
} );

describe( 'createRegistry', () => {
let registry;

Expand Down

0 comments on commit dc48adb

Please sign in to comment.