UNPKG

ember-concurrency

Version:

Improved concurrency/async primitives for Ember.js

90 lines (87 loc) 3 kB
import { TYPE_QUEUED, TYPE_STARTED, TYPE_CANCELLED } from './policies/execution-states.js'; const LAST_APPLIED_TAGS = new Map(); class Refresh { constructor(schedulerPolicy, stateTracker, taskInstances) { this.stateTracker = stateTracker; this.schedulerPolicy = schedulerPolicy; this.initialTaskInstances = taskInstances; this.startingInstances = []; } process() { let [taskInstances, numRunning, numQueued] = this.filterFinishedTaskInstances(); let reducer = this.schedulerPolicy.makeReducer(numRunning, numQueued); let finalTaskInstances = taskInstances.filter(taskInstance => { return this.setTaskInstanceExecutionState(taskInstance, reducer.step()); }); this.stateTracker.computeFinalStates(state => this.applyState(state)); this.startingInstances.forEach(taskInstance => taskInstance.start()); return finalTaskInstances; } filterFinishedTaskInstances() { let numRunning = 0, numQueued = 0; let taskInstances = this.initialTaskInstances.filter(taskInstance => { let taskState = this.stateTracker.stateFor(taskInstance.task); let executorState = taskInstance.executor.state; if (executorState.isFinished) { taskState.onCompletion(taskInstance); return false; } if (executorState.hasStarted) { numRunning += 1; } else { numQueued += 1; } return true; }); return [taskInstances, numRunning, numQueued]; } setTaskInstanceExecutionState(taskInstance, desiredState) { let taskState = this.stateTracker.stateFor(taskInstance.task); if (!taskInstance.executor.counted) { taskInstance.executor.counted = true; taskState.onPerformed(taskInstance); } switch (desiredState.type) { case TYPE_CANCELLED: // this will cause a follow up flush which will detect and recompute cancellation state taskInstance.cancel(desiredState.reason); return false; case TYPE_STARTED: if (!taskInstance.executor.state.hasStarted) { this.startingInstances.push(taskInstance); taskState.onStart(taskInstance); } taskState.onRunning(taskInstance); return true; case TYPE_QUEUED: taskState.onQueued(taskInstance); // TODO: assert taskInstance hasn't started? // Or perhaps this can be a way to pause a task? return true; } } applyState(state) { let { taskable } = state; if (!taskable.onState) { return; } const { guid } = taskable; if (LAST_APPLIED_TAGS.has(guid) && state.tag < LAST_APPLIED_TAGS.get(guid)) { return; } let props = Object.assign({ numRunning: state.numRunning, numQueued: state.numQueued, numPerformedInc: state.numPerformedInc }, state.attrs); taskable.onState(props, taskable); LAST_APPLIED_TAGS.set(guid, state.tag); } } export { Refresh as default }; //# sourceMappingURL=refresh.js.map