-
Notifications
You must be signed in to change notification settings - Fork 29
Encourage coarser mags when annotating a high number of voxels #8961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 49 commits
c4ba568
f6074a1
98d45b2
cfae01d
425959b
5819d92
683849c
fa10734
461fc7a
a5fbb91
18fc591
977f391
2012b1b
63c6332
c956a5b
38df61b
63129bb
9e916a2
fd7e73c
a9aa7ad
a9165c5
c6af70d
f8bf436
613f58b
9f22533
1696a6b
b68663f
3a1463f
dc774c1
1edc7e8
64093d5
b00c9c9
5a7d667
401e815
87e68b5
3f61c1a
658c788
7411227
2fcf0b9
8425875
62f6537
b1d5b8b
df150ca
f5bc27f
91ce0e0
7797555
a1c09f8
0fb2b1b
d99173d
a236ebe
44fcad1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,7 @@ import type DataCube from "viewer/model/bucket_data_handling/data_cube"; | |
| import { createCompressedUpdateBucketActions } from "viewer/model/bucket_data_handling/wkstore_adapter"; | ||
| import Store from "viewer/store"; | ||
| import { escalateErrorAction } from "../actions/actions"; | ||
| import { pushSaveQueueTransaction } from "../actions/save_actions"; | ||
| import { notifyAboutUpdatedBucketsAction, pushSaveQueueTransaction } from "../actions/save_actions"; | ||
| import type { UpdateActionWithoutIsolationRequirement } from "../sagas/volume/update_actions"; | ||
|
|
||
| // Only process the PushQueue after there was no user interaction (or bucket modification due to | ||
|
|
@@ -155,7 +155,8 @@ class PushQueue { | |
| createCompressedUpdateBucketActions(batch), | ||
| ); | ||
| Store.dispatch(pushSaveQueueTransaction(items)); | ||
|
|
||
| Store.dispatch(notifyAboutUpdatedBucketsAction(items.length)); | ||
| console.log("notify about ", items.length, " items"); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove |
||
| this.compressingBucketCount -= batch.length; | ||
| } catch (error) { | ||
| // See other usage of escalateErrorAction for a detailed explanation. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,84 @@ | ||||||||||||
| import { Button, Checkbox, type CheckboxChangeEvent, Space } from "antd"; | ||||||||||||
| import Toast from "libs/toast"; | ||||||||||||
| import UserLocalStorage from "libs/user_local_storage"; | ||||||||||||
| import { takeEvery } from "typed-redux-saga"; | ||||||||||||
| import type { Saga } from "viewer/model/sagas/effect-generators"; | ||||||||||||
|
|
||||||||||||
| const TOO_MANY_BUCKETS_TOAST_KEY = "manyBucketUpdatesWarningToast"; | ||||||||||||
| const WARNING_SUPPRESSION_USER_STORAGE_KEY = "suppressBucketWarning"; | ||||||||||||
|
|
||||||||||||
| function* manyBucketUpdatesWarning(): Saga<void> { | ||||||||||||
| let dontShowAgainInThisSession = false; | ||||||||||||
| const setDontShowAgainInThisSession = (value: boolean) => { | ||||||||||||
| dontShowAgainInThisSession = value; | ||||||||||||
| }; | ||||||||||||
| setInterval(() => { | ||||||||||||
| UserLocalStorage.setItem("suppressBucketWarning", "false"); | ||||||||||||
| console.log("resetting suppressBucketWarning to false every 120s for dev purposes"); | ||||||||||||
| }, 120 * 1000); | ||||||||||||
| //TODO_C dev | ||||||||||||
|
Comment on lines
16
to
20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove dev-only code before merge. This setInterval resets the user's suppression preference every 120 seconds, which would break the "never show again" functionality in production. Per the PR objectives, all dev-only changes must be removed before merge. Apply this diff to remove the dev code: - setInterval(() => {
- UserLocalStorage.setItem("suppressBucketWarning", "false");
- console.log("resetting suppressBucketWarning to false every 120s for dev purposes");
- }, 120 * 1000);
- //TODO_C dev
-📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||
|
|
||||||||||||
| function* showWarningToast(): Saga<void> { | ||||||||||||
| let neverShowAgain = false; | ||||||||||||
|
|
||||||||||||
| const onClose = () => { | ||||||||||||
| Toast.notificationAPI?.destroy(TOO_MANY_BUCKETS_TOAST_KEY); | ||||||||||||
| UserLocalStorage.setItem(WARNING_SUPPRESSION_USER_STORAGE_KEY, neverShowAgain.toString()); | ||||||||||||
| }; | ||||||||||||
| const handleCheckboxChange = (event: CheckboxChangeEvent) => { | ||||||||||||
| neverShowAgain = event.target.checked; | ||||||||||||
| }; | ||||||||||||
|
|
||||||||||||
| const warningMessage = | ||||||||||||
| "You are annotating a large area with fine magnifications. This can significantly slow down WEBKNOSSOS. Consider creating an annotation or annotation layer with restricted magnifications."; | ||||||||||||
| const linkToDocs = | ||||||||||||
| "https://docs.webknossos.org/volume_annotation/import_export.html#restricting-magnifications"; | ||||||||||||
| const neverShowAgainCheckbox = ( | ||||||||||||
| <Checkbox onChange={handleCheckboxChange} style={{ marginTop: "8px", marginBottom: "5px" }}> | ||||||||||||
| Never show this again | ||||||||||||
| </Checkbox> | ||||||||||||
| ); | ||||||||||||
| const closeButton = <Button onClick={onClose}>Close</Button>; | ||||||||||||
| const linkToDocsButton = ( | ||||||||||||
| <Button href={linkToDocs} target="_blank" rel="noopener noreferrer" type="primary"> | ||||||||||||
| Learn how | ||||||||||||
| </Button> | ||||||||||||
| ); | ||||||||||||
| const footer = ( | ||||||||||||
| <Space> | ||||||||||||
| {linkToDocsButton} | ||||||||||||
| {closeButton} | ||||||||||||
| </Space> | ||||||||||||
| ); | ||||||||||||
|
|
||||||||||||
| const suppressManyBucketUpdatesWarning = UserLocalStorage.getItem( | ||||||||||||
| WARNING_SUPPRESSION_USER_STORAGE_KEY, | ||||||||||||
| ); | ||||||||||||
|
|
||||||||||||
| if (suppressManyBucketUpdatesWarning !== "true" && dontShowAgainInThisSession !== true) { | ||||||||||||
| console.warn(warningMessage + " For more info, visit: " + linkToDocs); | ||||||||||||
| Toast.warning( | ||||||||||||
| <> | ||||||||||||
| {warningMessage} | ||||||||||||
| <br /> | ||||||||||||
| {neverShowAgainCheckbox} | ||||||||||||
| </>, | ||||||||||||
| { | ||||||||||||
| customFooter: footer, | ||||||||||||
| key: TOO_MANY_BUCKETS_TOAST_KEY, | ||||||||||||
| sticky: true, | ||||||||||||
| onClose, | ||||||||||||
| className: "many-bucket-updates-warning", | ||||||||||||
| }, | ||||||||||||
| ); | ||||||||||||
| setDontShowAgainInThisSession(true); | ||||||||||||
| } else { | ||||||||||||
| console.log("suppressing warning toast"); //TODO_C dev | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| yield takeEvery("SHOW_MANY_BUCKET_UPDATES_WARNING", showWarningToast); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| export default function* manyBucketUpdatesWarningSaga(): Saga<void> { | ||||||||||||
| yield takeEvery("WK_READY", manyBucketUpdatesWarning); | ||||||||||||
| } | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,24 @@ | ||
| import { getUpdateActionLog } from "admin/rest_api"; | ||
| import features from "features"; | ||
| import ErrorHandling from "libs/error_handling"; | ||
| import Toast from "libs/toast"; | ||
| import { sleep } from "libs/utils"; | ||
| import _ from "lodash"; | ||
| import { call, fork, put, takeEvery } from "typed-redux-saga"; | ||
| import { call, delay, fork, put, takeEvery } from "typed-redux-saga"; | ||
| import type { APIUpdateActionBatch } from "types/api_types"; | ||
| import { getLayerByName, getMappingInfo } from "viewer/model/accessors/dataset_accessor"; | ||
| import { setVersionNumberAction } from "viewer/model/actions/save_actions"; | ||
| import { showManyBucketUpdatesWarningAction } from "viewer/model/actions/annotation_actions"; | ||
| import { | ||
| type NotifyAboutUpdatedBucketsAction, | ||
| setVersionNumberAction, | ||
| } from "viewer/model/actions/save_actions"; | ||
| import { applySkeletonUpdateActionsFromServerAction } from "viewer/model/actions/skeletontracing_actions"; | ||
| import { applyVolumeUpdateActionsFromServerAction } from "viewer/model/actions/volumetracing_actions"; | ||
| import { globalPositionToBucketPositionWithMag } from "viewer/model/helpers/position_converter"; | ||
| import type { Saga } from "viewer/model/sagas/effect-generators"; | ||
| import { select } from "viewer/model/sagas/effect-generators"; | ||
| import { ensureWkReady } from "viewer/model/sagas/ready_sagas"; | ||
| import { Model } from "viewer/singletons"; | ||
| import { Model, Store } from "viewer/singletons"; | ||
| import type { SkeletonTracing, VolumeTracing } from "viewer/store"; | ||
| import { takeEveryWithBatchActionSupport } from "../saga_helpers"; | ||
| import { updateLocalHdf5Mapping } from "../volume/mapping_saga"; | ||
|
|
@@ -31,11 +36,48 @@ export function* setupSavingToServer(): Saga<void> { | |
| yield* takeEvery("INITIALIZE_ANNOTATION_WITH_TRACINGS", setupSavingForAnnotation); | ||
| yield* takeEveryWithBatchActionSupport("INITIALIZE_SKELETONTRACING", setupSavingForTracingType); | ||
| yield* takeEveryWithBatchActionSupport("INITIALIZE_VOLUMETRACING", setupSavingForTracingType); | ||
| yield* takeEvery("WK_READY", watchForNumberOfBucketsInSaveQueue); | ||
| } | ||
|
|
||
| const VERSION_POLL_INTERVAL_COLLAB = 10 * 1000; | ||
| const VERSION_POLL_INTERVAL_READ_ONLY = 60 * 1000; | ||
| const VERSION_POLL_INTERVAL_SINGLE_EDITOR = 30 * 1000; | ||
| // interval at which the number of buckets in save queue is checked | ||
| const CHECK_NUMBER_OF_BUCKETS_IN_SAVE_QUEUE_INTERVAL_MS = 10 * 1000; | ||
| // sliding time window for which the number of buckets in save queue is summed up | ||
| const CHECK_NUMBER_OF_BUCKETS_SLIDING_WINDOW_MS = 120 * 1000; | ||
|
|
||
| function* watchForNumberOfBucketsInSaveQueue(): Saga<void> { | ||
| const bucketSaveWarningThreshold = features().bucketSaveWarningThreshold; | ||
| let bucketsForCurrentInterval = 0; | ||
| let currentBucketCounts: Array<number> = []; | ||
| const bucketCountArrayLength = Math.floor( | ||
| CHECK_NUMBER_OF_BUCKETS_SLIDING_WINDOW_MS / CHECK_NUMBER_OF_BUCKETS_IN_SAVE_QUEUE_INTERVAL_MS, | ||
| ); | ||
| yield* takeEvery("NOTIFY_ABOUT_UPDATED_BUCKETS", (action: NotifyAboutUpdatedBucketsAction) => { | ||
| bucketsForCurrentInterval += action.count; | ||
| }); | ||
| while (true) { | ||
| yield* delay(CHECK_NUMBER_OF_BUCKETS_IN_SAVE_QUEUE_INTERVAL_MS); | ||
| const sumOfBuckets = _.sum(currentBucketCounts); | ||
| console.log( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reminder to remove |
||
| "buckets in last interval: ", | ||
| bucketsForCurrentInterval, | ||
| "currentBucketsArray: ", | ||
| currentBucketCounts, | ||
| "sumOfBuckets: ", | ||
| sumOfBuckets, | ||
| ); | ||
| if (sumOfBuckets > bucketSaveWarningThreshold) { | ||
| Store.dispatch(showManyBucketUpdatesWarningAction()); | ||
| } | ||
| currentBucketCounts.push(bucketsForCurrentInterval); | ||
| if (currentBucketCounts.length > bucketCountArrayLength) { | ||
| currentBucketCounts.shift(); | ||
| } | ||
| bucketsForCurrentInterval = 0; | ||
| } | ||
| } | ||
|
|
||
| function* watchForSaveConflicts(): Saga<void> { | ||
| function* checkForNewVersion(): Saga<boolean> { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.