Skip to content

CachedTopicRepository: Reconcile or invalidate cache after a failed or partial Save() #156

Description

@JeremyCaney

CachedTopicRepository wraps SqlTopicRepository and is registered as a singleton (e.g., via the activator), so its in-memory tree persists across requests rather than being reloaded per request. If a Save() fails or only partially persists (see #155), the cache's tree may no longer reflect what actually made it to the database. A subsequent Save() against that same cached tree then walks a Children collection that's missing topics SQL already has rows for, so TopicFactory.Create() adds new topics with the same keys instead of detecting the existing ones. Since there's no unique constraint on (ParentID, TopicKey) in the Topics table, these duplicate siblings persist silently until the application is restarted.

Implementation Notes

On a Save() failure (or, once #155 is deployed, whenever the wrapped SqlTopicRepository.Save() throws), CachedTopicRepository should invalidate the cached subtree it attempted to save rather than leaving it in an uncertain state—either by evicting the affected topics so the next Load() re-reads from SQL, or by re-running Load() itself against the wrapped repository to resynchronize before returning the caller.

Affected Files

  • OnTopic.Data.Caching/CachedTopicRepository.cs

Tasks

  • Catch Save() failures from the wrapped repository in CachedTopicRepository
  • Invalidate or refresh the affected cached subtree when a Save() fails
  • Add a test confirming that a failed Save() followed by a Load() reflects the wrapped repository's actual state, not stale cached data
  • Cross-reference SqlTopicRepository.Save(): Wrap recursive in a single transaction #155, since a non-transactional partial save is the scenario most likely to trigger this divergence between the cache and the database

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Area: RepositoriesRelates to the `ITopicRepository` interface or one of its implementations.Priority: 2Status 1: RoadmapPlanned for a future, indeterminate release.Type: BugBehavior that is inconsistent with documented or expected behavior.

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions