[go: up one dir, main page]

Page MenuHomePhabricator

"Register for event" should appear in event page header when user is logged out
Closed, ResolvedPublicBUG REPORT

Description

Steps to replicate the issue

What happens?

  • "Register for event" button does not appear

Screen Shot 2023-01-09 at 4.10.36 PM.png (198ร—2 px, 46 KB)

What should have happened instead?:

  • "Register for event" button appears; when clicked user is prompted to create a new Meta-Wiki account

Screen Shot 2023-01-09 at 4.31.15 PM.png (182ร—1 px, 48 KB)

Browser info

Event Timeline

Restricted Application added a subscriber: Aklapper. ยท View Herald TranscriptJan 9 2023, 9:33 PM

Good catch Lauren - this is a curious bug... A note for when we estimate this - the following test events which I just created do display the register button when logged out.
https://meta.wikimedia.org/wiki/Event:Sandbox/VWalters-WMF/qte-test2
https://test.wikipedia.org/wiki/Event:Sandbox/QTE-CampaignEvents0/qte-test

Interesting, I'm also able to see the register button on https://meta.wikimedia.org/wiki/Event:Sandbox/VWalters-WMF/qte-test2 when logged out.
Just as one more data point, I believe @VPuffetMichel was able to see the register button on https://meta.wikimedia.org/wiki/Event:WikiPolis_Yaound%C3%A9 when logged out.

Weirdly, we tested this again as a group today and could not reproduce the issue. Moving to backlog for now; we will monitor to see if it comes up again.

I think the behaviour described here can only happen if your IP address is blocked. However, this wouldn't be intermittent, and it would not change across different browsers or events. Can any of you verify if your IP address is blocked on meta? Maybe if you're using a VPN or something. Unfortunately, I'm not able to reproduce the issue on any page or browser.

Update: we eventually realized that this is a caching issue. As I wrote above, the only reason why the button may not show is if you're blocked. What likely happened is that someone whose IP is blocked visited the event page while logged out, that version was cached, and is then being served to all logged-out users. In particular, different data centers can have different cached versions, so you may or may not be able to reproduce the bug on a certain page depending on your geographical location (unless you force the connection to a specific data center).

We discussed this yesterday with Daniel, and a possible solution we talked about is to unconditionally display the "Register" button to logged-out users; if they're actually blocked, we will say so when they click the button. This is subpar UX, but it's what we already do with the "Edit" buton. However, on second thought, this is not sufficient. The content of the header is generally dynamic, and it does not change on page edit, meaning logged-out users may also see outdated information on location, time, number of participants, etc. Also, the "register" button may be missing if the event has ended or registration is closed. No changes to either of these things would purge the cache. This means that even if we unconditionally show the "register" button, it wouldn't be the end of the story. On top of that, the content of the "more details" header is also cached (because it's generated in the backend), meaning other things like the list of participants are cached. And finally, if someone registers publicly and then switches to private, their name might be cached by accident.

All in all, this means that we most likely shouldn't allow the header to be cached as aggressively as the rest of the page. However, disabling caching for the whole page also seems a bad idea, especially because the lack of caching can be exploited by malicious actors. Maybe a better solution would be to manually purge the cache whenever something about the event changes. We would also still need to unconditionally show the "Register" button to logged-out users, because we can't otherwise vary the cache by blocked status.

Note that this may further be improved by adding some JS code that checks the blocked status on page load and hides the button if the user is blocked (or the other way around).

Thanks @Daimona, is the solution you mention hard to implement (I mean manually purge the cache)?
I agree that we should always show the register button.
If the page is outdated, it will become up to date after the user login, right?

Thanks @Daimona, is the solution you mention hard to implement (I mean manually purge the cache)?

It should not be terribly hard, we can use HtmlCacheUpdater to purge the cache whenever something changes. The problem is when exactly we need to do that. It's not just after a registration is updated, but also when someone registers or changes the status of their registration, and also when an event ends.

If the page is outdated, it will become up to date after the user login, right?

Yes, logged-in page views are not cacheable.


All in all, I don't think this is a huge task, but it's also not the "just fix this conditional in a two-line change" kind of bug. Also, since this has to do with caching and we all know how hard cache invalidation is, I'm really erring on the side of caution.

Thinking about this a bit more, I'm not sure if we should also purge the cache whenever someone registers. If we do that, anyone would be able to force cache purges by simply registering->unregistering->registering->... This is quite similar to page edits though. We'd have the same potential issue with editing the registration itself, but that's less of a concern because organizers are trusted, I believe.

@ldelench_wmf @VPuffetMichel @cmelo @MHorsey-WMF I'm thinking that maybe we should reach out to the performance team to validate this approach, see if there are any alternatives, etc. WDYT?

Sounds good to me! We can reach out to Performance via any of the methods listed here. Please holler if you need any help coordinating this.

Sounds good to me too.

Summary for the performance team:

  • What is the problem you are trying to solve?
    • We're embedding a dynamic (user-dependent) header in page views with details about the event (date, time, participants, etc.) and a button that lets you register for the event, if you are not blocked. The content of the header can be different for different users, and may change if an event changes or if a new participant registers. As for all page views, the html of the page is cached by Varnish for all logged-out requests, which has two unwanted consequences:
      • The button itself is also cached, meaning that if the page is first rendered for a blocked user, any logged-out user who will visit the page wil see the cached version without the button.
      • The usernames of participants are also cached. We have a feature where users can register anonymously for T&S reasons, in which case their username is not shown. If someone registers publicly, the page gets cached, and then that person changes their registration to be anonymous, the cached version would still show their username.
    • Note that only registered users can register for events, and clicking the button when logged out will bring you to the login page.
  • Solutions you considered so far
    • Disabling caching for all event pages seems an overkill. The solution we considered is to first make the info header not user-dependent (almost; in practice, we would still show the button to all logged-out users, even if they're blocked). Then, we would purge the cache every time the event information (date, time etc.) changes, when someone (un)registers, and possibly when the event ends (to hide the button).
  • From our guidelines, which metrics you are thinking about using
    • We haven't thought about this.

Thanks for the summary @Daimona
Please fill out the metrics you are going to be using before the meeting on Monday. You can find more guidance on our backend and frontend guides

Thanks for the summary @Daimona
Please fill out the metrics you are going to be using before the meeting on Monday. You can find more guidance on our backend and frontend guides

I read those pages, but I'm not sure about metrics in this context (this is also something that we did not discuss as a team). There are a few quantities we can measure here: how often the cache is purged, how long it takes for the page to re-render, cache hit ratio... However, some of these are out of our control and we already have metrics for them (i.e., rendering time); I'm not sure if measuring cache purges would be useful, because that's a user-initiated action, and what we wanted to better understand is the impact/sustainability of such action, regardless of how often it happens. I'm unsure what else we might do, but I'd be happy do discuss these in greater detail once a solution is identified.

After talking with Performance-Team, we know that we have the following options:

  • Reduce the TTL of the cache to something sufficiently short (e.g., 5 minutes). This means that the outdated version may still linger around for a while, but that's gonna be an issue anyway (even cache purges are not immediate).
  • Purge the cache when the event data changes, as proposed above.

Leaving at least some caching in place (as in both options above, and as opposed to disabling the cache for event pages) would still be very beneficial, e.g. if there's a surge of page views for a certain page. We could also use both options at the same time. For instance, shorten the TTL if we know the event's end date is approaching, and purge the cache whenever possible.

Also, we're gonna make the header not vary by user (e.g., blocked status) for logged-out users. We might then add some JavaScript to hide the button on the fly.

Also, we're gonna make the header not vary by user (e.g., blocked status) for logged-out users. We might then add some JavaScript to hide the button on the fly.

Actually, we don't need any JavaScript. If the user is logged-out, the button is always going to redirect to Special:Login. Even if the IP is blocked, the user may have an account that they can log into (if they aren't hardblocked), so showing the button would make sense.

Change 895755 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/extensions/CampaignEvents@master] Make the registration header not vary by user for logged-out requests

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

Change 895755 merged by jenkins-bot:

[mediawiki/extensions/CampaignEvents@master] Make the registration header not vary by user for logged-out requests

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

Change 896088 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/extensions/CampaignEvents@master] Make sure that event pages are not cached beyond the event end date

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

Change 896349 had a related patch set uploaded (by Daimona Eaytoy; author: Daimona Eaytoy):

[mediawiki/extensions/CampaignEvents@master] Purge event page cache when event changes or user (un)registers

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

Change 896088 merged by jenkins-bot:

[mediawiki/extensions/CampaignEvents@master] Make sure that event pages are not cached beyond the event end date

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

Change 896349 merged by jenkins-bot:

[mediawiki/extensions/CampaignEvents@master] Purge event page cache when event changes or user (un)registers

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

This bug was caused by CDN caching, and it's going to be difficult to test. This is a potential testing strategy that could be used.

As a preliminary step, create an event page and enable registration on it.

First test

This is not related to caching, it's only about blocked users. Log in with a blocked account and go to the event page. Verify that the "Register for event" button is not shown. Then block your IP address (I'd suggest using a VPN for that, the IP may even be already blocked), and visit the event page while logged-out. Verify that the button is shown.

Second test

This one has to do with caching. You can use dev tools to see whether the page was served from cache, by checking the "x-cache-status" header in the response (hit, miss, bypass). Note that the cache is always bypassed for logged-in requests. Here, we want to verify that certain "changes" to an event will purge the cache of the event page. These "changes" are:

  • Edits to the event information (like dates, address, etc.); you may want to repeat the test a few times while changing different fields.
  • Waiting for the event end time to finish (i.e., wait until after the event end time)
  • Someone registering privately for the event (or changing public registration to private)
  • Someone canceling their registration for the event

For each of the above scenarios, the test should go something like this:

  1. Visit the event page
  2. Make sure that the CDN cached the page, by opening it while logged out and checking the response headers
  3. Make the change to the event (one from the list above). Do not visit the event page with your organizer account.
  4. Go to the event page while logged out, verify that you got a cache miss and that the information on the page (registration header and "more details" dialog) is up-to-date
    • In particular, changes to the event information should be reflected in both the header and dialog. Changes to the participants should be reflected in the "N participants" label in the header, and in the list of participants inside the dialog. When the event is over, the "Register for event" button should be replaced by a disabled button that reads "Event ended"

Just an update on this, I am waiting for the correct permissions on test wiki to be able to test this.

I am testing only the Second test as noted above in T326593#8791418:

On initial page load in incognito window, x-cache status is "hit-front"

Screenshot 2023-06-02 at 2.47.55 PM.png (1ร—3 px, 787 KB)

Then in a separate window, I logged in as organizer, and changed the start date
Then refreshed the page in a logged out incognito window
after refresh, the displayed information is up to date, x-cache statue is "pass"
changing start date, refreshing in logged out incognito window, cache pass.png (1ร—3 px, 774 KB)

When repeating the above test, but instead changing the Event meeting type, x-cache status is "miss"

Screenshot 2023-06-02 at 2.50.07 PM.png (1ร—3 px, 772 KB)

I then repeated it again, changing only the date, and the x-cache status is "miss"... so am not sure why sometimes it is "pass" and sometimes "miss" but the information shown in the logged out page is all correct. As I changed various fields and repeated the test above, it was always correctly shown as "miss" except the one time documented above that was a "pass".


โŒ When registering for an event it is incorrectly holding onto the cache. To reproduce, log in as a non-organizer, register for the event. In an incognito window, while logged out, hard refresh the event and check the number of participants, and the x-cache status. The cache does not break, and the number of participants is incorrect. See video below, and you can test with this event https://test.wikipedia.org/wiki/Event:T326593 :

Screen Recording 2023-06-02 at 3.26.58 PM.gif (756ร—1 px, 2 MB)

I also tested this with private registration, which worked correctly, and then again with public registration... and it worked correctly. But then tried with public registration again and it failed (did not break the cache or display correct participant count). It always seems to work correctly for private registration, but sometimes continues to fail on public registration. So the issue still seems to be intermittent.

Here is a clip of many hard refreshes to attempt to get a cache miss for a logged out account, and no avail:

Screen Recording 2023-06-02 at 3.42.37 PM.gif (567ร—1 px, 1 MB)


Because I am able to get the number of participants to update correctly when registering privately though, I am able to test the cancel registration, and it is correctly breaking the cache:

Screen Recording 2023-06-02 at 3.49.48 PM.gif (945ร—1 px, 2 MB)


The cache also breaks correctly when opening the event and viewing in logged out incognito tab:

Screen Recording 2023-06-02 at 4.01.58 PM.gif (945ร—1 px, 2 MB)

and also works correctly when closing the event and viewing in a logged out incognito tab:

Screen Recording 2023-06-02 at 4.10.35 PM.gif (945ร—1 px, 2 MB)


And it also correctly breaks the cache when the event ends:

Screen Recording 2023-06-02 at 4.17.52 PM.gif (1ร—3 px, 2 MB)


@Daimona the tl;dr from above is the only real problem that I can find with this right now is that public registration doesn't seem to be breaking the cache.

I then repeated it again, changing only the date, and the x-cache status is "miss"... so am not sure why sometimes it is "pass" and sometimes "miss" but the information shown in the logged out page is all correct. As I changed various fields and repeated the test above, it was always correctly shown as "miss" except the one time documented above that was a "pass".

I'm not sure why the cache would be bypassed sometimes, but at any rate, if the cache is bypassed users still get the fresh version of the page, so that should be good.

โŒ When registering for an event it is incorrectly holding onto the cache. To reproduce, log in as a non-organizer, register for the event. In an incognito window, while logged out, hard refresh the event and check the number of participants, and the x-cache status. The cache does not break, and the number of participants is incorrect. See video below, and you can test with this event https://test.wikipedia.org/wiki/Event:T326593 :

I see from the video that you registered publicly; in this case, we intentionally do not purge the cache, as an optimization, cfr. T326593#8791418:

  • Someone registering privately for the event (or changing public registration to private)

This does mean that you can get outdated information, but at least there's no leak of private information. We might consider changing that in the future if there's a need for it.

I also tested this with private registration, which worked correctly, and then again with public registration... and it worked correctly. But then tried with public registration again and it failed (did not break the cache or display correct participant count). It always seems to work correctly for private registration, but sometimes continues to fail on public registration. So the issue still seems to be intermittent.

This looks pretty much the expected behaviour, except for the intermittence. I don't have an explanation for it, but since we intentionally tolerate cache hits when someone registers publicly, I think it's OK.

โŒ When registering for an event it is incorrectly holding onto the cache. To reproduce, log in as a non-organizer, register for the event. In an incognito window, while logged out, hard refresh the event and check the number of participants, and the x-cache status. The cache does not break, and the number of participants is incorrect. See video below, and you can test with this event https://test.wikipedia.org/wiki/Event:T326593 :

I see from the video that you registered publicly; in this case, we intentionally do not purge the cache, as an optimization, cfr. T326593#8791418:

  • Someone registering privately for the event (or changing public registration to private)

This does mean that you can get outdated information, but at least there's no leak of private information. We might consider changing that in the future if there's a need for it.

Ahhhh, okay I didn't get that the cache was intentionally not purged for public registration. In any case, it does not affect the Register for event button in the AC.


Also pertaining to First test on T326593#8791418, when logging in as user QTE-CampaignEvents1 that was blocked through Special:Block on test wiki, the Register button correctly does not display

Screenshot 2023-06-06 at 3.53.36 PM.png (1ร—2 px, 294 KB)


When blocking at IP address though (IPv4 or IPv6), the Register for event button still displays, whether the user is logged in or not. Testing with IP blocks through Special:Block and this event.

Screenshot 2023-06-06 at 4.12.59 PM.png (826ร—1 px, 142 KB)

Screenshot 2023-06-06 at 4.13.49 PM.png (766ร—1 px, 94 KB)


When blocking at IP address though (IPv4 or IPv6), the Register for event button still displays, whether the user is logged in or not. Testing with IP blocks through Special:Block and this event.

Thanks, this looks good to me. The logged-out case is intentional, as noted in T326593#8791418:

Then block your IP address (I'd suggest using a VPN for that, the IP may even be already blocked), and visit the event page while logged-out. Verify that the button is shown.

The point being that all logged-out users should be served the same version, regardless of user blocks.

The logged-in case is also working correctly I believe: even if your IP is blocked, your account isn't blocked (unless the block was a hardblock and your account is not ipblock exempt, but that's not the case here), so you should be able to register as usual.

When blocking at IP address though (IPv4 or IPv6), the Register for event button still displays, whether the user is logged in or not. Testing with IP blocks through Special:Block and this event.

Thanks, this looks good to me. The logged-out case is intentional, as noted in T326593#8791418:

Then block your IP address (I'd suggest using a VPN for that, the IP may even be already blocked), and visit the event page while logged-out. Verify that the button is shown.

The point being that all logged-out users should be served the same version, regardless of user blocks.

The logged-in case is also working correctly I believe: even if your IP is blocked, your account isn't blocked (unless the block was a hardblock and your account is not ipblock exempt, but that's not the case here), so you should be able to register as usual.

Okay, I am going to mark this as done / resolved then.