Skip to content

Commit 4d9e7f3

Browse files
committed
add comments and prioritize consumption of user action in diffing sagas
1 parent 59a30c4 commit 4d9e7f3

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

frontend/javascripts/viewer/model.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,20 @@ export class WebKnossosModel {
344344
};
345345

346346
ensureSavedState = async () => {
347-
// This function will only return once all state is saved
348-
// even if new updates are pushed to the save queue during saving
347+
/* This function will only return once all state is saved
348+
* even if new updates are pushed to the save queue during saving
349+
*/
350+
351+
// This is a helper function which ensures that the diffing sagas
352+
// have seen the newest tracings. These sagas are responsible for diffing
353+
// old vs. new tracings to fill the save queue with update actions.
354+
// waitForDifferResponses dispatches a special action which the diffing sagas
355+
// will respond to be calling the callback that is attached to the action.
356+
// That way, we can be sure that the diffing sagas have processed all user actions
357+
// up until the time of where waitForDifferResponses was invoked.
349358
async function waitForDifferResponses() {
350359
const { annotation } = Store.getState();
360+
// All skeleton and volume tracings should respond to the dispatched again.
351361
const tracingIds = new Set(
352362
_.compact([annotation.skeleton?.tracingId, ...annotation.volumes.map((t) => t.tracingId)]),
353363
);

frontend/javascripts/viewer/model/actions/save_actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export const dispatchRedoAsync = async (dispatch: Dispatch<any>): Promise<void>
126126
await readyDeferred.promise();
127127
};
128128

129+
// See Model.ensureSavedState for an explanation of this action.
129130
export const ensureTracingsWereDiffedToSaveQueueAction = (callback: (tracingId: string) => void) =>
130131
({
131132
type: "ENSURE_TRACINGS_WERE_DIFFED_TO_SAVE_QUEUE",

frontend/javascripts/viewer/model/sagas/save_saga.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import window, { alert, document, location } from "libs/window";
77
import _ from "lodash";
88
import memoizeOne from "memoize-one";
99
import messages from "messages";
10+
import { buffers } from "redux-saga";
1011
import { actionChannel, call, delay, fork, put, race, take } from "typed-redux-saga";
1112
import { ControlModeEnum } from "viewer/constants";
1213
import { getMagInfo } from "viewer/model/accessors/dataset_accessor";
@@ -53,6 +54,7 @@ import type {
5354
SkeletonTracing,
5455
VolumeTracing,
5556
} from "viewer/store";
57+
import type { Action } from "../actions/actions";
5658
import { takeEveryWithBatchActionSupport } from "./saga_helpers";
5759

5860
const ONE_YEAR_MS = 365 * 24 * 3600 * 1000;
@@ -388,6 +390,7 @@ export function* setupSavingForTracingType(
388390
let prevTdCamera = yield* select((state) => state.viewModeData.plane.tdCamera);
389391
yield* call(ensureWkReady);
390392

393+
const actionBuffer = buffers.expanding<Action>();
391394
const tracingActionChannel = yield* actionChannel(
392395
tracingType === "skeleton"
393396
? [
@@ -399,20 +402,30 @@ export function* setupSavingForTracingType(
399402
"SET_TRACING",
400403
]
401404
: [...VolumeTracingSaveRelevantActions, ...FlycamActions, ...ViewModeSaveRelevantActions],
405+
actionBuffer,
402406
);
407+
408+
// See Model.ensureSavedState for an explanation of this action channel.
403409
const ensureDiffedChannel = yield* actionChannel<EnsureTracingsWereDiffedToSaveQueueAction>(
404410
"ENSURE_TRACINGS_WERE_DIFFED_TO_SAVE_QUEUE",
405411
);
406412

407413
while (true) {
408-
// todop: prioritize tracingAction?
409-
const { ensureAction } = yield* race({
410-
_tracingAction: take(tracingActionChannel),
411-
ensureAction: take(ensureDiffedChannel),
412-
});
413-
if (ensureAction != null) {
414-
ensureAction.callback(tracingId);
415-
continue;
414+
// Prioritize consumption of tracingActionChannel since we don't want to
415+
// reply to the ENSURE_TRACINGS_WERE_DIFFED_TO_SAVE_QUEUE action if there
416+
// are unprocessed user actions.
417+
if (!actionBuffer.isEmpty()) {
418+
yield* take(tracingActionChannel);
419+
} else {
420+
// Wait for either a user action or the "ensureAction".
421+
const { ensureAction } = yield* race({
422+
_tracingAction: take(tracingActionChannel),
423+
ensureAction: take(ensureDiffedChannel),
424+
});
425+
if (ensureAction != null) {
426+
ensureAction.callback(tracingId);
427+
continue;
428+
}
416429
}
417430

418431
// The allowUpdate setting could have changed in the meantime

0 commit comments

Comments
 (0)