Guppy implements a task queue for any actions that require exclusive access to the project's package.json
and/or node_modules
folder.
This currently includes dependency installation & uninstallation.
The queue has the following structure:
{
[projectId: string]: Array<{
action: 'install' : 'uninstall' : 'modify',
active: true | false,
...extras,
}>
}
The extras
keys are any key-value pairs specific to the action (think of them like key-value pairs added to Redux actions).
Each queueable action should have, at minimum, 4 action creators:
QUEUEABLE_ACTION_ADD
QUEUEABLE_ACTION_QUEUE
QUEUEABLE_ACTION_START
QUEUEABLE_ACTION_FINISH
QUEUEABLE_ACTION_ADD
should fire when the user indicates the action should take placeQUEUEABLE_ACTION_QUEUE
should add the action to the queueQUEUEABLE_ACTION_START
should handle starting the action once it gains priority on the queueQUEUEABLE_ACTION_FINISH
should handle any cleanup or results of the action, and start the next queued action
QUEUEABLE_ACTION_ADD
should be handled in a saga, and should follow this pattern:
export function* handleQueueableActionAdd({ projectId }) {
// check if the project has an active queue
const queuedAction = yield select(getNextActionForProjectId, projectId);
// fire the `QUEUEABLE_ACTION_QUEUE` action to add the action to the queue
yield put(queueableActionQueue(projectId));
// if the queue was previously empty, start the first action in the queue
// (the one we just queued)
if (!queuedAction) {
yield put(startNextActionInQueue(projectId));
}
}
The first item in a queue will always be the action that is being currently processed, with the active
key set to true
.
As soon as the action is completed, it is removed from the queue and the next action in the queue becomes the first and has it's active
key set to true
.
This repeats until the queue is finished.