Page MenuHomePhabricator

Back out the change that changed action=purge to require a confirmation page
Open, Needs TriagePublic

Assigned To
None
Authored By
Xaosflux
Aug 22 2016, 12:38 AM
Referenced Files
None
Tokens
"Like" token, awarded by MGChecker."Love" token, awarded by Jack_who_built_the_house."Like" token, awarded by Kharkiv07."Love" token, awarded by Pppery.

Description

A recent WMF-wide change is now requiring an unwanted manual confirmation when invoking the PURGE action. The change was made because of the multi-datacenter "project, of which one of the requirements is that no database write actions happen on GET requests."

This appears to be the same type of unwanted confirmation behavior that was presented when T136375 was requested to rollback T88044

Screenshots here:
https://commons.wikimedia.org/wiki/File:Mediawiki-bad-purge-20160821-Capture.PNG
https://commons.wikimedia.org/wiki/File:Mediawiki-bad-purge-20160821-Capture-tr.PNG

See also https://en.wikipedia.org/wiki/Wikipedia:Village_pump_(technical)#Purge_links_require_confirmation_step

Expected behavior: Passing action=purge should trigger a page cache purge
Current behavior: A second page is being loaded, manually requiring users with purge access to confirm their request

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Anomie subscribed.

Removing MediaWiki-Action-API: This has nothing to do with the action API, https://gerrit.wikimedia.org/r/#/c/288462/ has not been merged.

Xaosflux added a project: MediaWiki-General.

Please undo - this is another example of breaking changes being introduced without having a good evaluation of user needs first. It should have been fairly trivial to determine that &action=purge was actually being used via server logs, prior to making this breaking change

This task feels like a duplicate of T143435, which I personally think is largely a duplicate of other tasks including T135170.

This wasn't done just for the sake of making it difficult for users. There are actual valid technical reasons as stated on T135170 so it won't be reverted just because of it.

Apparently, I also had been visiting the ?action=purge URLs rather commonly and I was also finding this annoying (even though it's just one extra click and a slowdown). So I wrote and enabled https://meta.wikimedia.org/wiki/User:Glaisher/autoPurge.js which tries to imitate the behavior. However, it is slower than previously because it's a client-side script. There are also other gadgets like UTC clock and Purge tab which would work okay without navigating you to ?action=purge and won't require a confirmation step (though they don't have the previous behavior for purge action page).

Is there any problem about this change other than the extra confirmation step?

At least 200 wiki, thousand of pages, and I don't know how many Help Page to be update. It was probably better to think before you make the change

The description of T135170 wrote "Any gadgets/JS for users with 'purge' rights can be updated to use POST instead of GET." This ignores the fact that many pages have direct purge links, such as https://en.wikipedia.org/wiki/Category:Pending_AfC_submissions in the progress indicator. Action should be taken to restore these to their prior behaviour. At the very least @Glaisher 's script or something like it should be incorporated into site JS for logged-in users.

Two questions ...

  1. Is there any point to the "purge" right now?
  2. Is requiring POST the first step toward requiring a token?

... and an observation.
The code at https://meta.wikimedia.org/wiki/User:Glaisher/autoPurge.js kind of points out the uselessness of requiring users to use POST if JavaScript can just transparently translate the GET to a POST, anyway. Unless there's some value in causing discomfort to people with JavaScript disabled. I would expect the snippet to become the most universally implemented shim in the MediaWiki world.

To my understanding, translating GET to POST via JS is not a problem, applying GET directly to the request is, see T135170#2310146

To my understanding, translating GET to POST via JS is not a problem, applying GET directly to the request is, see T135170#2310146

Since it's Krinkle's comment, he'd be the best one to clear up any misunderstanding, but I believe he was making a point about the ease with which people could cause a database write simply by adding a GET query. Whether action=purge is submitted via GET or POST, I would expect that its effect on the infrastructure (database, cache, whatever else) should be the same.

It's not a matter of the easiness or difficulty of the request. GET/POST distinction is going to be used for checking whether the request is a read-only and if so to route the request accordingly in a multi-datacenter setup. Your expectation about GET/POST is also wrong as GET is actually supposed to be retrieving data only not for modifying; it wasn't respected previously.

... Your expectation about GET/POST is also wrong as GET is actually supposed to be retrieving data only not for modifying; ....

Bold added.

I think that's a statement about philosophy. Before the current change, action=purge as a GET would purge, and action=purge as a POST would purge. Now there's no such thing as action=purge as a GET, because the confirmation page turns it into a POST.

So this is a change to make implementation match philosophy. Okay, and there's no going back from that.

Going forward, your script (or something like it) should be deployed in Common.js or maybe as a gadget on Wikipedia (etc.) ASAP. It probably would have been better to do that before requiring POST, but here we are now. The screams are only going to get louder.

@Unready regarding, "the ease with which people could cause a database write simply by adding a GET query", yes it is easy - that is what we LIKE about it. We can provide easy one clicks for even the newest editors to get current versions.

Here are some good example of when editor need to purge a page:

https://en.wikipedia.org/wiki/Category:Candidates_for_speedy_deletion (PURGE button)
https://en.wikipedia.org/wiki/Wikipedia:Articles_for_deletion

We want them to see the current versions, but don't expect them to go adding custom java scripts or gadgets.

I think that's a statement about philosophy. Before the current change, action=purge as a GET would purge, and action=purge as a POST would purge. Now there's no such thing as action=purge as a GET, because the confirmation page turns it into a POST.

So this is a change to make implementation match philosophy. Okay, and there's no going back from that.

The change was not merely to make the implementation match philosophy if you considered the rest of what I wrote. Note that the work to make GET requests idempotent has been ongoing for months now and this is just one part of it.

Going forward, your script (or something like it) should be deployed in Common.js or maybe as a gadget on Wikipedia (etc.) ASAP. It probably would have been better to do that before requiring POST, but here we are now. The screams are only going to get louder.

Ideally T56902: Deprecate and remove the purge action from MediaWiki should be resolved and we wouldn't need to have to do manual purges at all but that is unlikely to happen in the foreseeable future. I can submit a patch to core with that script improved to imitate the previous behavior (the exact behavior cannot be achieved since it will have to be done client-side) if someone (from Performance team?) can confirm that it can actually work reliably.

The change was not merely to make the implementation match philosophy if you considered the rest of what I wrote. Note that the work to make GET requests idempotent has been ongoing for months now and this is just one part of it.

... and it is has been pointed out that a merge of the T135170 change causes process disruption [0]. Yet and as so often opinions from users are just ignored and brushed away to the overall goals. While the technical argument (GET vs. POST) has been understood, the situation remains dire and unsatisfactory for users that rely on purge to work as it did.

[0] https://phabricator.wikimedia.org/T135170#2299301

The change was not merely to make the implementation match philosophy if you considered the rest of what I wrote. Note that the work to make GET requests idempotent has been ongoing for months now and this is just one part of it.

The purge action already is idempotent - purging the same page twice has no effect unless changes have been made to any of the templates it transcludes.

... and it is has been pointed out that a merge of the T135170 change causes process disruption [0]. Yet and as so often opinions from users are just ignored and brushed away to the overall goals. While the technical argument (GET vs. POST) has been understood, the situation remains dire and unsatisfactory for users that rely on purge to work as it did.

[0] https://phabricator.wikimedia.org/T135170#2299301

Dire? Are you joking?

The purge action already is idempotent - purging the same page twice has no effect unless changes have been made to any of the templates it transcludes.

When does idempotent ever mean "doesn't change after the first time"? The initial (first) purge action very often changes server state.

Technically purge is not idempotent when highly dynamic content is included, like {{CURRENTTIMESTAMP}}.

In any case, GET requests should be as "nullipotent" as possible, which is stricter than "idempotent".

Going forward, your script (or something like it) should be deployed in Common.js or maybe as a gadget on Wikipedia (etc.) ASAP. It probably would have been better to do that before requiring POST, but here we are now. The screams are only going to get louder.

.... I can submit a patch to core with that script improved to imitate the previous behavior (the exact behavior cannot be achieved since it will have to be done client-side) if someone (from Performance team?) can confirm that it can actually work reliably.

Can I suggest something more like

mw.loader.using( [ 'mediawiki.api' ], function () {
	if ( mw.config.get( 'wgAction' ) !== 'purge' ) {
		return;
	}
	new mw.Api().post( {
		action: 'purge',
		titles: mw.config.get( 'wgPageName' )
	} ).then( function () {
		location.replace( 
			location.pathname +
			location.search
				.replace( /(?:\?|&)action=purge$/ , '' )
				.replace( /(\?|&)action=purge&/ , '$1' ) +
			location.hash
		);
	}, function ( e ) {
		console.log( 'Purge failed', e );
	} );
} );

to preserve other query parameters and the fragment, if any? ... or its equivalent in PHP if that's how it's implemented?

The purge action already is idempotent - purging the same page twice has no effect unless changes have been made to any of the templates it transcludes.

When does idempotent ever mean "doesn't change after the first time"? The initial (first) purge action very often changes server state.

According to Wiktionary, idempotent means

Said of a function: describing an action which, when performed multiple times on the same subject, has no further effect on its subject after the first time it is performed.

That clearly agrees with me.

The purge action already is idempotent - purging the same page twice has no effect unless changes have been made to any of the templates it transcludes.

When does idempotent ever mean "doesn't change after the first time"? The initial (first) purge action very often changes server state.

According to Wiktionary, idempotent means

Said of a function: describing an action which, when performed multiple times on the same subject, has no further effect on its subject after the first time it is performed.

That clearly agrees with me.

The Wiktionary entry certainly agrees with you, yes.

RFC 2616, establishing HTTP, says:

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

Source: https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.

You seem to be saying in this task that the side-effects of a single request should not/will not match those of multiple requests. That sounds like the opposite of what the spec intended.

@Xaosflux: Should this task be re-focused on providing logged-in users with a way to purge a page with a single click (i.e., without an additional confirmation)?

The task as written suggests that purge behavior (itself) has broken, which seems inaccurate.

Xaosflux renamed this task from Back out the changes that broke action=purge behavior to Back out the change that changed action=purge to require a confirmation page.Aug 23 2016, 1:37 AM

@MZMcBride I re-titled the request

The purge action already is idempotent - purging the same page twice has no effect unless changes have been made to any of the templates it transcludes.

When does idempotent ever mean "doesn't change after the first time"? The initial (first) purge action very often changes server state.

According to Wiktionary, idempotent means

Said of a function: describing an action which, when performed multiple times on the same subject, has no further effect on its subject after the first time it is performed.

That clearly agrees with me.

The Wiktionary entry certainly agrees with you, yes.

RFC 2616, establishing HTTP, says:

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

Source: https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.

You seem to be saying in this task that the side-effects of a single request should not/will not match those of multiple requests. That sounds like the opposite of what the spec intended.

I think you are misunderstanding, MZMcBride. Ignoring pages than transclude magic words like {{CURRENTTIMESTAMP}}, purging the same page twice has no further effect. The RFC you cite seems to agree with the Wiktionary entry as well. In any case, this has degenerated into needless technical arguing about the meaning of idempotent that has no relevance to the actual issue.

Change 306325 had a related patch set uploaded (by Legoktm):
Automatically submit the form on action=purge with JavaScript

https://gerrit.wikimedia.org/r/306325

Ignoring pages than transclude magic words like {{CURRENTTIMESTAMP}}, purging the same page twice has no further effect.

That's not true. Purging a page will update page_touched to the current timestamp. If you purge it again, it will update it to the newer timestamp.

To summarize:

  • This change was motivated by the multi-dc project, of which one of the requirements is that no database write actions happen on GET requests. Most of these violations had already been cleaned up in the backend, only a few user facing actions like purge and rollback are left.
  • At this time we have no plans to back out this change and allow purges on direct GET requests.
  • Solutions that use JavaScript to bypass the form are *welcome*, I've submitted a patch that would auto-submit the form seen on ?action=purge.
  • To quote T56902, "Every time a user has to manually trigger a purge (or a null edit) to get a useful representation of some page, MediaWiki has failed that user." When merging this change, I did not anticipate how often people are apparently purging pages, and by consequence, how often we are failing those users by requiring them to purge. I would encourage people who purge regularly to comment on that ticket or file subtasks so we can fix those root bugs so purging is not necessary at all.

@Legoktm any update on your patch - This band aid is pretty sorry though - making what was one action for the end user to now be multiple actions to perform the same change.

T139893: In our education program we have, since this July, lost an automation in helping new editors contribute, as every new user now has to purge his main sandbox to see the changes in his list of sandboxed articles. 200 people have been taught to use these sandboxes so far, some make heavy use of the multi-sandbox functionality and our new education program is about to begin. Single click purging would help.

@Legoktm You wrote that "Solutions that use JavaScript to bypass the form are *welcome*", but may I ask the question? We on ruwiki are planning to make links that are created with "Purge" template perform POST request (and then reload the page) via site scripts. Should we add this functionality for all users, or are performance considerations significant enough so that we should do that only for registered users?

We on ruwiki are planning to make links that are created with "Purge" template perform POST request (and then reload the page) via site scripts. Should we add this functionality for all users, or are performance considerations significant enough so that we should do that only for registered users?

I think we should be looking at why purge links are necessary for any users. Users should not need to purge pages manually, cf. T56902: Deprecate and remove the purge action from MediaWiki.

I use purge links at my user subpage that contains a list of its subpages
inserted using social pages as template. But I don't use them often because
I usually remember its name. But this usually works quite fast (or I don't
need it faster). This is just a think that makes my life more easy if I
need the update immediately. That's the reason why I don't think purge
shouldn't be removed now.

I think it'll be okay only when the update will be made in every case
immediately.
But this isn't possible I think. If a template is in all pages and somebody
will need to have one page updated before the others it'll be impossible
without purge/nulledit.

Just a tip. Czech Wikipedia use a non-default gadget that adds a button to
more section in Vector. Maybe this can be useful for other project too.

Totally agree with @Urbanecm. Purge links seem to be a quite reasonable compromise between performance and the need of users to see something updated immediately. I guess the removal of the "purge" action and users whom MediaWiki never fails could be seen as a distant ideal, but not as a plan of action to implement in the nearest future.

Change 306325 abandoned by Legoktm:
Automatically submit the form on action=purge with JavaScript

https://gerrit.wikimedia.org/r/306325

Just a note, user script / js that mostly takes care of this is:

/* Override annoying purge dialog */
if ( mw.config.get( 'wgAction' ) === 'purge' ) {

$('form.mw-htmlform').submit();

}