Skip to content

Commit

Permalink
Add queue to client's operation dispatching (#356)
Browse files Browse the repository at this point in the history
We run the entire exchange pipeline synchronously,
since that's predictable, which is how Wonka's
sources work.

When an exchange dispatches an operation, for
instance with reexecuteOperation, this operation
is hence run immediately, which can be confusing
and lead to state that disagrees with itself,
since the operation is essentially then "nested".

Instead what we want is to queue operations up
if they're dispatched nestedly, so from inside
an exchange, and flush this queue after the
original dispatch has completed.
  • Loading branch information
kitten authored Jul 30, 2019
1 parent 09494f2 commit df6e090
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,24 @@ export class Client {
// called to dispatch a new operation on the subject
const [operations$, nextOperation] = makeSubject<Operation>();
this.operations$ = operations$;
this.dispatchOperation = nextOperation;

// Internally operations aren't always dispatched immediately
// Since exchanges can dispatch and reexecute operations themselves,
// if we're inside an exchange we instead queue the operation and flush
// them in order after
const queuedOperations: Operation[] = [];
let isDispatching = false;

this.dispatchOperation = (operation: Operation) => {
queuedOperations.push(operation);
if (!isDispatching) {
isDispatching = true;
let queued;
while ((queued = queuedOperations.shift()) !== undefined)
nextOperation(queued);
isDispatching = false;
}
};

const exchanges =
opts.exchanges !== undefined ? opts.exchanges : defaultExchanges;
Expand Down

0 comments on commit df6e090

Please sign in to comment.