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
Revert the order of page_restrictions rev key #718
Conversation
@@ -32,7 +32,7 @@ const tableName = 'title_revisions'; | |||
* @type {string} | |||
* @const | |||
*/ | |||
const restrictionsTableName = 'restrictions'; | |||
const restrictionsTableName = 'page_restrictions'; |
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.
A better name in any case.
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.
@gwicke Ye, we've needed to rename it anyways..
sys/parsoid.js
Outdated
@@ -318,7 +318,8 @@ class ParsoidService { | |||
// This revision is actually a redirect. Pass redirect target | |||
// to caller, and let it rewrite the location header. | |||
resp.status = 302; | |||
resp.headers.location = encodeURIComponent(redirectTarget); | |||
// Filter will take care of uri-encoding | |||
resp.headers.location = redirectTarget; |
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.
This strikes me as a bit brittle. Is this mainly meant as a performance optimization, or is there another reason to defer encoding?
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.
@gwicke To be able to share the same codepath within the filter
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.
Could the decoding be done once in the filter & the result be stored in a local variable? The performance impact should be pretty small, and in exchange we'd avoid introducing an exception to the "regular HTTP headers" principle & assumptions about which filters are active.
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.
A that's possible. But that would mean doing encode-decode-encode cycle instead of just one encode
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.
Yeah, but a) redirects are rare, and b) encoding & decoding a small string is fairly cheap. IMHO, consistency & lack of coupling is more important.
@@ -261,7 +262,8 @@ class PRS { | |||
storePageDeletion(hyper, req, revision) { | |||
return this.storeRestrictions(hyper, req, { | |||
title: req.params.title, | |||
rev: req.params.revision || revision.rev, | |||
// We're storing page_deletions with magic 0 rev just to update the static column |
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.
Perhaps also worth mentioning that 0 is chosen so that it will always match for any query for less-or-equal some revision greater than 0.
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.
{{done}}
lib/access_check_filter.js
Outdated
@@ -64,6 +66,9 @@ module.exports = (hyper, req, next, options, specInfo) => { | |||
} | |||
|
|||
return contentPromise.then((content) => redirect(content, location, options)); | |||
} else if (content.status === 302) { |
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.
Is the intention here to override stored redirects?
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.
We return 302 when content's not in storage && it's a redirect. For ?redirect=false
and some other conditions we don't what 302 but want 200 instead
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.
To me it looks as if this condition would fire when content was in storage, but the restriction table did not have the redirect. Is that intended?
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.
@gwicke nono. We're only setting 302 in parsoid.js when the content was not in storage because in that case restriction table update would be concurrent with the content request because we've just parsed out the redirect.
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.
When we're taking the content from the storage we don't set 302 and rely on the filter to get it from the restrictions table
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 see -- that's pretty subtle. Do you think an explaining comment here could be helpful to remind ourselves about how this interacts with parsoid.js?
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 that in the perfect world we wouldn't have such a weird hard dependency at all, but I couldn't think of a way to get rid of it. I'd add a comment
LGTM overall, just a couple of questions in line. |
3f17420
to
5b0d6fd
Compare
@gwicke Updated to address your comments |
5b0d6fd
to
80e50c7
Compare
I've rebased the PR on top of the latest master. The tests are currently failing, see the Phablet ticket for an explanation why are they failing and a discussion on what to do with that. |
I've adapted the patch to the new storage (we don't need to supply a tacky artificial fixed Also this one already starts using the new filter to demonstrate that the tests are passing. However, we need to revert that part before deploying because we don't have the restrictions filled in and also we wanna make a proxy to run both filters in parallel in the beginning and check that the results are correct. Before building the proxy filter I will do some manual correctness testing though. |
I did manually test this locally and in vagrant for various scenarios of page creation/renaming/deleting/redirecting etc and it seems to work correct for all the cases I'm managed to imagine. TODO: Create a proxy that will run both filters and compare the results. |
@@ -64,6 +67,12 @@ module.exports = (hyper, req, next, options, specInfo) => { | |||
} | |||
|
|||
return contentPromise.then(content => redirect(content, location, options)); | |||
} else if (content.status === 302) { | |||
// Parsoid.js emits a redirect when the new content is parsed because | |||
// there could be a race condition with updating a restriction table. |
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.
Is this about the time window between a new restriction being created (ex: revision suppressed), and the update for this being processed in ChangeProp?
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.
Yup.
👍 |
Change-Id: I067887abf493a6fbb51ba3530443ee26c6c484c5
Change-Id: I2c0db7395a5e553e4e5307d004831b98722b2b3d
7cf2766
to
88e706a
Compare
Finally ready! |
Change-Id: I84e22519126bf9677ed9e17ec1d52a32227a0c20
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.
LGTM in general, one in-lined question. Also, it would be best if we created the Cass3 tables before we merge this, so as not to shoot ourselves in the foot.
} else if (content.status === 302) { | ||
// Parsoid.js emits a redirect when the new content is parsed because | ||
// there could be a race condition with updating a restriction table. | ||
// If the client doesn't want a redirect - remove it. |
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.
How can we know for sure that the client doesn't want a redirect here simply based on the status code (which implies otherwise) ?
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.
This is inside an else-if clause, if client wanted a redirect or we wanted to provide it - we wouldn've going into the if clause and never even evaluated this condition comparing the status to 302
Final polish needed to enable the restrictions table. Still need to reload the data to the new table and backfill the redirects, but overall we're good to go. All unit tests pass (sqlite depends on wikimedia/restbase-mod-table-sqlite#37)
Done a quite extensive testing pass in vagrant, all looks good. Vagrant depends on https://gerrit.wikimedia.org/r/#/c/322358/
Bug: https://phabricator.wikimedia.org/T149965