Skip to content
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

Need optional chaining in MemoryCache::removeInverseRelationshipsSync() #970

Closed
bradjones1 opened this issue Aug 27, 2022 · 4 comments
Closed

Comments

@bradjones1
Copy link
Contributor

removeInverseRelationshipsSync(
relationships: RecordRelationshipIdentity[]
): void {
relationships.forEach((r) => {
let rels = this._inverseRelationships[r.relatedRecord.type].get(
r.relatedRecord.id
);
if (rels) {

I believe this .get() should be ?.get() as I've discovered that relationships may be dangling after prior remove operations. The if (rels) below indicates that we anticipate this but don't account for it during the get.

This is a potential bug I've discovered while working through some situations where I'm trying to prune the cache of certain records to ensure I have an updated set from a coordinated remote source... However, it's proving difficult to remove records without also removing inverse relationships, which isn't my intent (I'm fine with them dangling.)

@bradjones1 bradjones1 changed the title Need optional chaining in MemoryCache::removeInverseRelationshipsSync()` Need optional chaining in MemoryCache::removeInverseRelationshipsSync() Aug 27, 2022
@dgeb
Copy link
Member

dgeb commented Aug 31, 2022

@bradjones1 this._inverseRelationships is set in _resetInverseRelationships for every model in the schema. I don't think there's a normal code path by which this._inverseRelationships[SOME_TYPE] gets cleared. But if there is, then we should defend against this in a number of code paths, not just in removeInverseRelationshipsSync.

Are you saying that you're manually clearing out this._inverseRelationships[SOME_TYPE] during a cleanup process? Any chance you can provide a failing test that illustrates your particular scenario?

@bradjones1
Copy link
Contributor Author

@dgeb Thanks for taking a look. The scenario is that I want to ensure that I have a "complete" cache client side of a particular resource type. I store information in a non-Orbit flag that tells me if I think I need to basically clear my local cache of all instances of the resource, and then re-request from the remote, to ensure I have a complete set, and no stale resources that might have gone away from the remote. However, this resource is also linked to from other resource types. So when I iterate through all the resource IDs locally and delete them, all those references get deleted, as well. (I would prefer they just be dangling.) And thus I run into an error where the cache has inconsistent inverse relationships. In a way, I'd kinda just rather not track them, but I imagine this is core to Orbit's functionality.

I know that's clear as mud, but hopefully that provides some context until I can generate a failing test case, or you tell me that this is all a very bad idea and anti-pattern and breaks on purpose.

@dgeb
Copy link
Member

dgeb commented Sep 1, 2022

In a way, I'd kinda just rather not track them, but I imagine this is core to Orbit's functionality.

@bradjones1 Tracking inverse relationships is the responsibility of the SyncCacheIntegrityProcessor. By default cache processors are set to [SyncSchemaConsistencyProcessor, SyncCacheIntegrityProcessor].

However, you can optionally leave this processor out when creating a cache like so:

const source = new MemorySource({ schema, cacheSettings: { processors: [SyncSchemaConsistencyProcessor] } });

@bradjones1
Copy link
Contributor Author

OK, thanks for the detailed reply. I think this is then more a +1 to document these various processors and their roles in the official docs, a la #955.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants