-
Notifications
You must be signed in to change notification settings - Fork 450
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
Support query subscriptions on projections with a filter not in the projection fields #316
Conversation
…ns on projections with a filter not in the projection fields
Thanks for your work on this @ericyhwang! I wonder if #199 is affected by this change and whether your PR would satisfy their concern. |
Make it easier to find the implementation of the DB used for tests
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.
I made some additional significant changes:
- Added the test that Eric wrote. By including it here, it will run against memory-db as well as sharedb-mongo
- Removed the shallow op cloning from pubsub and put it in agent, which now clones immediately before calling sanitizeOp, so it is more clear that it is passing in just a shallow instead of a deep clone
- Kept the idea of doing a nextTick before calling into projections or
op
middleware, but doing it in agent instead of query emitter. The same op objects are emitted from pubsub directly to agent for document subscriptions, so if we're going to do that, we need to make sure that all of sharedb's internal pubsub to query emitter is synchronous and then we have an async delay before any user code runs. Depending on the order that listeners are subscribed, doc streams could be getting ops pushed to them before query emitter streams. - Removed everything related to projections from op-stream. Projections are now only done in backend.js for ops that are fetched from the db, and in agent.js for ops that come from pubsub or query streams
- Now returning ops in addition to streams from backend.subscribe and backend.subscribeBulk. Previously, these ops were pushed into the stream. By returning them separately, we can sanitize them first. We don't have to copy these ops, since they come from the db. In addition, this ends up changing the order to send the fetched ops first before any ops that may have been in the stream from pubsub. This should be better, because the pubsub ops are likely to have missed ops, and we want to send the oldest ops first so that the client is able to apply them. It can't apply the ops from pubsub if there was a gap.
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.
Your new changes on top LGTM!
I can't approve this since I created the PR, so you'll have to do so.
Co-Authored-By: Eric Hwang <[email protected]>
Prior to this PR, if you issue a query subscription on a projection, with a filter field that's not in the projection fields, then an op to change that filter field will not trigger the query to update.
This is because the op projection (
_sanitizeOp
) was happening prior to theskipPoll
checks, which are what determine if an op could affect a query. A projected op would appear like it doesn't affect the query.The fix is to defer applying projections to query ops until after the
skipPoll
checks.I couldn't write a unit test in this repo, since the MemoryDB's query implementation always returns all docs in the collection, regardless of query filters. See below for the test I'll be adding to sharedb-mongo to cover this case.
Test I'll be adding to sharedb-mongo, which fails prior to this change and succeeds after this change: