-
Notifications
You must be signed in to change notification settings - Fork 23
Fix annotation layer initialization race condition #1578
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: main
Are you sure you want to change the base?
Conversation
Defer annotation layer creation to onMounted with nextTick and requestAnimationFrame to ensure GeoJS viewer is fully initialized before creating layers. This fixes an intermittent bug where annotations would not display on first load but would appear correctly after exiting and re-entering the viewer. Changes: - Add layersInitialized ref to track initialization state - Move layer creation to initializeLayers() called in onMounted - Use nextTick + requestAnimationFrame to ensure GeoJS render cycle completes before layer creation - Add guards in updateLayers() and updateAttributes() to prevent calls before initialization - Move event listener setup to setupEventListeners() called after layer initialization Addresses: #365 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BryonLewis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a fix at all, a ton of rearranging code that doesn't do anything to address the reference issue. Doesn't fix #365 at all because if I remove the second updateLayers call it does the same thing asif I removed the [0,1].forEach(() => updateLayers());
| requestAnimationFrame(() => { | ||
| updateLayers( | ||
| frameNumberRef.value, | ||
| editingModeRef.value, | ||
| selectedTrackIdRef.value, | ||
| multiSeletListRef.value, | ||
| enabledTracksRef.value, | ||
| visibleModesRef.value, | ||
| selectedKeyRef.value, | ||
| props.colorBy, | ||
| ); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For all this code it doesn't fix a thing. It's still calling a double updateLayers to draw the first version. I pulled and checked this. This is not the solution to the related bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, the previous approach was flawed. I've updated the fix to properly address the root cause.
The Problem:
The original code (and my first attempt) used timing heuristics (onMounted → nextTick → requestAnimationFrame) hoping the GeoJS viewer would be ready. But the viewer is created asynchronously in the annotator when the first image loads - there's no guarantee timing-based approaches will work.
The Actual Fix:
Instead of guessing with timing, LayerManager now watches annotator.ready.value:
watch(
() => annotator.ready.value,
(ready) => {
if (ready && !layersInitialized.value) {
initializeLayers();
updateLayers(...);
}
},
{ immediate: true },
);This required exposing the existing state.ready property through the MediaController interface. The annotator components already set ready=true only after initializeViewer() completes, so this properly synchronizes layer creation with viewer initialization.
I also removed the double updateLayers() call since, as you pointed out, it was cargo cult code that never actually fixed anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still doesn't fix the issue of first time rendering when loading data and introduces more issues, including issues with the geoJS layer annotation-clicked handler. That state.ready variable is true before the watcher is even run so it never has a chance to be false inside of the LayerManager either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damnit claude.
This issue came about when I noticed some annotations still didn't show in the viewer the first time I went into them (but showed in the list). The initial commit seemed to make it go away, but it's a non-deterministic issue so hard to say.
f3d0ac0 to
255b12e
Compare
The previous commit used timing heuristics (onMounted + nextTick + requestAnimationFrame) which cannot reliably wait for the GeoJS viewer since it's initialized asynchronously when the first image/video loads. This commit properly synchronizes layer creation with viewer initialization: - Add `ready` property to MediaController interface - Expose existing state.ready through the mediaController object - Replace timing heuristics in LayerManager with a watch on annotator.ready.value that triggers layer initialization only when the viewer is actually ready - Remove redundant double-call to updateLayers() The annotator components set ready=true only after initializeViewer() completes, guaranteeing geoViewerRef.value is initialized before use. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
255b12e to
a8abca5
Compare
Defer annotation layer creation to onMounted with nextTick and requestAnimationFrame to ensure GeoJS viewer is fully initialized before creating layers. This fixes an intermittent bug where annotations would not display on first load but would appear correctly after exiting and re-entering the viewer.
Changes:
Addresses: #365