-
Notifications
You must be signed in to change notification settings - Fork 90
Preview: per-row eventstamp-based etags for submissions-geojson #1718
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
base: master
Are you sure you want to change the base?
Preview: per-row eventstamp-based etags for submissions-geojson #1718
Conversation
| const getSubmissionSelectionEtag = (formPK, odataQuery) => ({ db }) => | ||
| db.oneFirst(sql` | ||
| SELECT | ||
| format('%s.%s', coalesce(max(sub.event), 0), count(sub.event)) |
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 think count(*) would be faster than count(sub.event). Output wise both are same in a sense that sub.event can't be null ever, right?
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.
IIUC count(*) lets PG choose which index to use to do the count on (to avoid a row scan). If it's being very very smart then that indeed could be faster (perhaps it has just been reading the PK index or something). I just happen to know that event has an index on it so the count() wouldn't result in a row scan. But yeah it's unlikely we'd ever get into the situation in which this count will result in a rowscan, we'd have to lose the PK index. I'll just change it for the less specific count(*) then.
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.
Output wise both are same in a sense that
sub.eventcan't be null ever, right?
They might be the same at this very start but they won't stay the same, a) because the counter is global, b) because of rows being deleted.
| FROM | ||
| submissions sub | ||
| WHERE | ||
| sub."formId" = ${formPK} |
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.
what will happen if the Form or Project is deleted?
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.
There's this FK:
"submissions_formid_foreign" FOREIGN KEY ("formId") REFERENCES forms(id) ON DELETE CASCADE
so there shouldn't be any orphaned submissions. The next request (potentially conditional) would 404, we won't even get to the etag calculation. Is that what you mean?
sadiqkhoja
left a comment
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.
can you please add tests to ensure that ETag gets updated on the events that should trigger cache invalidation.
As an alternative to maintaining a whole comprehensive compendium of if-this-then-thats at the API level, I propose I'll just test the trigger itself, and thus whether insertions/mutations are indeed eventstamped. And then later once (or if?) we add transparent caching through nginx, I'd like to test the behaviour of the caching infra as a whole, thus with nginx and its rather specific configuration in the loop. |
Towards getodk/central#1439
Stacks onto:
and as such, contains code from those that's not yet in master, and this PR should not be merged, so I'm leaving it as draft.
Also, I'm still thinking about a way to handle the fact that the OData filter may refer to columns not present in the tables used in the etag calculation (case in point:
ffgeo.path), and I'm still thinking about a way to make that calculation more reusable.Anyway, the commit to actually look at is fabc4d0 !
The blessed alternative to:
This introduces the first use of the
submissionstable's per-row eventstamps as etags.It's a micro-PR to validate the approach.
Approach, reasoning:
with_etag()doesn't really lend itself to that. It's a hard thing to accomplish anyway as for revalidation, you'd basically have to feed the etag to the DB and let it do some kind of awkward to express early return escapades to avoid recalculation if the etag matches, and if it doesn't, also somehow return the new etag together with the result.What has been done to verify that this works as intended?
So far, reasoning.
Why is this the best possible solution? Were any other approaches considered?
How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
N/A
Does this change require updates to the API documentation? If so, please update docs/api.yaml as part of this PR.
N/A
Before submitting this PR, please make sure you have:
make testand confirmed all checks still pass OR confirm CircleCI build passes