Skip to content

Clear CompoundAnnotation Cache on Task Changes #8756

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

Merged
merged 5 commits into from
Jul 8, 2025
Merged

Conversation

fm3
Copy link
Member

@fm3 fm3 commented Jul 7, 2025

When finishing or cancelling a task annotation, clear the compound annotation caches that this annotation influences.

That way, when reloading the compound annotation afterwards, the new data is visible there immediately.

Note that the tracingstore-side caches don’t need to be cleared, as the wk side will decide to put new data there, containing the new merged annotationProto (with all-new tracingIds for the layers).

URL of deployed dev instance (used for testing):

Steps to test:

  • Create a few tasks for a project
  • After finishing a task, view the CompoundProject
  • in another tab, finish a second task
  • Reload the CompoundProject tab, should show the new data.

Issues:


  • Added changelog entry (create a $PR_NUMBER.md file in unreleased_changes or use ./tools/create-changelog-entry.py)
  • Considered common edge cases

@fm3 fm3 self-assigned this Jul 7, 2025
Copy link
Contributor

coderabbitai bot commented Jul 7, 2025

📝 Walkthrough

Walkthrough

The changes introduce cache invalidation logic for compound annotation views when tasks are finished, cancelled, or reopened. This involves updating controllers and services to clear related cached annotations, renaming a caching flag for clarity, and adding a cache removal method. These updates ensure compound annotation data remains current.

Changes

File(s) Change Summary
app/controllers/AnnotationController.scala Added taskService dependency; clear compound cache on reopen/cancel; updated cancellation logic.
app/models/annotation/AnnotationService.scala Clear compound cache in finish method when annotation has an associated task.
app/models/annotation/AnnotationStore.scala Renamed cache to useCache; added removeFromCache method for annotation cache removal.
app/models/annotation/handler/AnnotationInformationHandler.scala,
app/models/annotation/handler/SavedTracingInformationHandler.scala
Renamed cache to useCache in trait and implementing class.
app/models/task/TaskService.scala Added clearCompoundCache method; inject AnnotationStore and TaskDAO.
unreleased_changes/8756.md Documented fix for outdated compound annotation views.

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Invalidate compound annotation cache when a task is finished, so new instances appear immediately (#8744)
Ensure cache is cleared on task cancel and reopen to prevent stale compound views (#8744)
Avoid unnecessary cache invalidation to prevent performance overhead (#8744)

Poem

In the warren where tasks are done,
Compound caches now swiftly run.
No more stale views, the data is fresh,
With clever code, the bugs enmesh.
Rabbits rejoice, the fix is clear—
Hopping along, the views appear!
🐇✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@fm3 fm3 changed the title WIP: Clear CompoundAnnotation Cache on Task Changes Clear CompoundAnnotation Cache on Task Changes Jul 7, 2025
@fm3 fm3 marked this pull request as ready for review July 7, 2025 09:13
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
unreleased_changes/8756.md (1)

1-2: Apply style improvements for better readability.

The static analysis tools have identified valid style suggestions:

-### Fixed
-- Fixed that compound (merged) views of tasks, projects and task types would sometimes show outdated annotation data, leaving out the data from recently finished tasks annotations.
+### Fixed
+- Fixed an issue where compound (merged) views of tasks, projects and task types would sometimes show outdated annotation data, omitting the data from recently finished task annotations.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14dbb8a and 025d787.

📒 Files selected for processing (7)
  • app/controllers/AnnotationController.scala (4 hunks)
  • app/models/annotation/AnnotationService.scala (1 hunks)
  • app/models/annotation/AnnotationStore.scala (3 hunks)
  • app/models/annotation/handler/AnnotationInformationHandler.scala (1 hunks)
  • app/models/annotation/handler/SavedTracingInformationHandler.scala (1 hunks)
  • app/models/task/TaskService.scala (3 hunks)
  • unreleased_changes/8756.md (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
app/models/annotation/handler/SavedTracingInformationHandler.scala (3)
Learnt from: frcroth
PR: scalableminds/webknossos#8236
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/mesh/NeuroglancerPrecomputedMeshFileService.scala:161-166
Timestamp: 2025-04-28T14:18:04.368Z
Learning: In Scala for-comprehensions with the Fox error handling monad, `Fox.fromBool()` expressions should use the `<-` binding operator instead of the `=` assignment operator to properly propagate error conditions. Using `=` will cause validation failures to be silently ignored.
Learnt from: frcroth
PR: scalableminds/webknossos#8236
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/mesh/MeshFileService.scala:170-173
Timestamp: 2025-04-23T08:51:57.756Z
Learning: In the webknossos codebase, classes extending `FoxImplicits` have access to an implicit conversion from `Option[A]` to `Fox[A]`, where `None` is converted to an empty Fox that fails gracefully in for-comprehensions.
Learnt from: MichaelBuessemeyer
PR: scalableminds/webknossos#8352
File: app/models/organization/CreditTransactionService.scala:0-0
Timestamp: 2025-01-27T12:06:42.865Z
Learning: In Scala's for-comprehension with Fox (Future-like type), the `<-` operator ensures sequential execution. If any step fails, the entire chain short-circuits and returns early, preventing subsequent operations from executing. This makes it safe to perform validation checks before database operations.
app/models/annotation/handler/AnnotationInformationHandler.scala (1)
Learnt from: frcroth
PR: scalableminds/webknossos#8236
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/mesh/MeshFileService.scala:170-173
Timestamp: 2025-04-23T08:51:57.756Z
Learning: In the webknossos codebase, classes extending `FoxImplicits` have access to an implicit conversion from `Option[A]` to `Fox[A]`, where `None` is converted to an empty Fox that fails gracefully in for-comprehensions.
app/models/annotation/AnnotationService.scala (1)
Learnt from: MichaelBuessemeyer
PR: scalableminds/webknossos#8352
File: app/models/organization/CreditTransactionService.scala:0-0
Timestamp: 2025-01-27T12:06:42.865Z
Learning: In Scala's for-comprehension with Fox (Future-like type), the `<-` operator ensures sequential execution. If any step fails, the entire chain short-circuits and returns early, preventing subsequent operations from executing. This makes it safe to perform validation checks before database operations.
app/models/task/TaskService.scala (3)
Learnt from: frcroth
PR: scalableminds/webknossos#8236
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/mesh/MeshFileService.scala:170-173
Timestamp: 2025-04-23T08:51:57.756Z
Learning: In the webknossos codebase, classes extending `FoxImplicits` have access to an implicit conversion from `Option[A]` to `Fox[A]`, where `None` is converted to an empty Fox that fails gracefully in for-comprehensions.
Learnt from: MichaelBuessemeyer
PR: scalableminds/webknossos#8352
File: app/models/organization/CreditTransactionService.scala:0-0
Timestamp: 2025-01-27T12:06:42.865Z
Learning: In Scala's for-comprehension with Fox (Future-like type), the `<-` operator ensures sequential execution. If any step fails, the entire chain short-circuits and returns early, preventing subsequent operations from executing. This makes it safe to perform validation checks before database operations.
Learnt from: frcroth
PR: scalableminds/webknossos#8236
File: webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/mesh/NeuroglancerPrecomputedMeshFileService.scala:161-166
Timestamp: 2025-04-28T14:18:04.368Z
Learning: In Scala for-comprehensions with the Fox error handling monad, `Fox.fromBool()` expressions should use the `<-` binding operator instead of the `=` assignment operator to properly propagate error conditions. Using `=` will cause validation failures to be silently ignored.
app/controllers/AnnotationController.scala (1)
Learnt from: frcroth
PR: scalableminds/webknossos#8609
File: app/models/dataset/Dataset.scala:753-775
Timestamp: 2025-05-12T13:07:29.637Z
Learning: In the `updateMags` method of DatasetMagsDAO (Scala), the code handles different dataset types distinctly:
1. Non-WKW datasets have `magsOpt` populated and use the first branch which includes axisOrder, channelIndex, and credentialId.
2. WKW datasets will have `wkwResolutionsOpt` populated and use the second branch which includes cubeLength.
3. The final branch is a fallback for legacy data.
This ensures appropriate fields are populated for each dataset type.
🧬 Code Graph Analysis (2)
app/models/annotation/handler/SavedTracingInformationHandler.scala (1)
app/models/annotation/handler/AnnotationInformationHandler.scala (1)
  • useCache (35-35)
app/models/annotation/AnnotationStore.scala (2)
app/models/annotation/handler/AnnotationInformationHandler.scala (1)
  • useCache (35-35)
app/models/annotation/AnnotationIdentifier.scala (1)
  • toUniqueString (11-14)
🪛 LanguageTool
unreleased_changes/8756.md

[duplication] ~1-~1: Possible typo: you repeated a word.
Context: ### Fixed - Fixed that compound (merged) views of tasks, ...

(ENGLISH_WORD_REPEAT_RULE)


[style] ~2-~2: To strengthen your wording, consider replacing the phrasal verb “leave out”.
Context: ...ometimes show outdated annotation data, leaving out the data from recently finished tasks a...

(OMIT_EXCLUDE)

🔇 Additional comments (12)
app/models/annotation/handler/AnnotationInformationHandler.scala (1)

35-35: LGTM! Clear naming improvement.

The rename from cache to useCache makes the method's intent more explicit and aligns with similar changes across the codebase.

app/models/annotation/handler/SavedTracingInformationHandler.scala (1)

27-27: LGTM! Consistent with trait method rename.

The variable rename maintains consistency with the trait method and preserves the existing behavior.

app/models/annotation/AnnotationStore.scala (2)

28-28: LGTM! Consistent naming updates.

The updates from handler.cache to handler.useCache maintain consistency with the trait and class renames.

Also applies to: 40-40


64-64: LGTM! Clean cache removal implementation.

The new removeFromCache method is well-implemented, leveraging the existing toUniqueString method for consistent key generation. The simple signature makes it easy to use from the cache clearing logic.

app/models/annotation/AnnotationService.scala (1)

316-316: LGTM! Proper cache invalidation integration.

The cache clearing logic is correctly integrated using Fox.runOptional to conditionally clear the compound cache only for task annotations. The placement after state updates ensures consistency, and the async execution avoids blocking the main workflow.

app/models/task/TaskService.scala (3)

8-8: Import addition looks correct.

The import of AnnotationStore and AnnotationIdentifier is properly added to support the new cache clearing functionality.


22-22: Constructor dependency injection is properly implemented.

The addition of annotationStore: AnnotationStore and taskDAO: TaskDAO dependencies follows the established pattern in the codebase.

Also applies to: 27-27


93-99: Cache clearing method is well-implemented.

The clearCompoundCache method correctly:

  • Fetches the task using GlobalAccessContext (appropriate for internal operations)
  • Removes three related cache entries for compound annotations
  • Uses Fox for proper error handling and sequential execution
  • Follows established patterns in the codebase

The logic ensures that all compound views (task, project, and task type) are invalidated when a task annotation changes state.

app/controllers/AnnotationController.scala (4)

20-20: Import addition is correct.

The import of TaskService is properly added to support the new cache clearing functionality.


55-55: Constructor dependency injection follows established patterns.

The addition of taskService: TaskService dependency is properly implemented.


162-162: Cache clearing in reopen method is correctly implemented.

The use of Fox.runOptional(annotation._task)(taskService.clearCompoundCache) properly clears the compound cache only when a task ID exists, which is appropriate for maintaining cache consistency after reopening an annotation.


303-313: Cancel method refactoring improves robustness and cache consistency.

The changes improve the implementation in several ways:

  • Pattern matching on (annotation._task, annotation.typ) ensures task annotations actually have a task ID
  • Conditional cache clearing only for previously finished annotations is logical since only finished annotations would affect compound caches
  • The sequential execution using Fox ensures proper error handling

The logic correctly handles the cache invalidation before state updates, which is appropriate since the cache will be rebuilt when needed.

@fm3 fm3 requested a review from MichaelBuessemeyer July 7, 2025 09:35
Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome(nauts) 🛰️ 👩‍🚀 👨‍🚀, works perfectly and lgmt :D

@fm3 fm3 enabled auto-merge (squash) July 8, 2025 08:13
@fm3 fm3 merged commit dd8c34c into master Jul 8, 2025
5 checks passed
@fm3 fm3 deleted the clear-compound-cache branch July 8, 2025 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalidate Cached Compound Annotations When More Instances Are Finished
2 participants