fix race condition in loading joined collections into live query#451
fix race condition in loading joined collections into live query#451
Conversation
🦋 Changeset detectedLatest commit: 30f29e4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 8 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
More templates
@tanstack/db
@tanstack/db-ivm
@tanstack/electric-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
| // filter out deletes for keys that have not been sent | ||
| continue | ||
| } | ||
| this.sentKeys.add(change.key) |
There was a problem hiding this comment.
We were only adding keys to the sentKeys when they were requested, not when they were send due to just watching the live changes.
|
Size Change: +25 B (+0.04%) Total Size: 64.3 kB
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 1.16 kB ℹ️ View Unchanged
|
kevin-dp
left a comment
There was a problem hiding this comment.
Great job, this was a really hard one to find!
I left two very minor comments.
| this.sendVisibleChangesToPipeline(changes, loadedInitialState) | ||
| // We are filtering the changes out when `sendChanges` is false, but still sending | ||
| // an empty array to the pipeline. This is needed to ensure that the pipeline | ||
| // receives the status update that the collection is now ready. |
There was a problem hiding this comment.
I would add some more comments explaining why the filtering is needed:
We filter out changes when
sendChangesis false to ensure that we don't send any changes from the live subscription until the join operator requests either the initial state or its first key. This is needed otherwise it could receive changes which are then later subsumed by the initial state (and that would lead to weird bugs due to the data being received twice).
| type Player = { id: number; name: string } | ||
| type Challenge = { id: number; value: number } | ||
|
|
||
| let playerBeginCallback: (() => void) | undefined |
There was a problem hiding this comment.
The code for creating the collections and storing their callbacks is the same for Players and challenges. Could define a helper function that does this such that we don't have to duplicate the code. And then just call it once per collection.
Fixes #438
The issue was that the subscription to the live changes could start emitting results before we had first done any join processing. The join called either
loadKeysorloadInitialStatedepending on if there was an index it could use. These now set a flag to indicate that we now actually want to start tailing the live changes, until then they are filtered out. We still have to send an empty array of changes when there are any before then so that the query is notified of any collection status change.Failed test run with repo before it's then fixed: https://github.com/TanStack/db/actions/runs/17233860827/job/48894002331?pr=451