Last modified: 2014-10-29 10:48:39 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T44815, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 42815 - Provide a robust way of logging events without blocking until network request completes; use sendBeacon with client-side storage fallback
Provide a robust way of logging events without blocking until network request...
Status: PATCH_TO_REVIEW
Product: Analytics
Classification: Unclassified
EventLogging (Other open bugs)
unspecified
All All
: High normal
: ---
Assigned To: Nobody - You can work on this!
:
Depends on: 64721
Blocks: 56426
  Show dependency treegraph
 
Reported: 2012-12-07 07:14 UTC by Matthew Flaschen
Modified: 2014-10-29 10:48 UTC (History)
10 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Matthew Flaschen 2012-12-07 07:14:10 UTC
Use HTML5 storage as an intermediary queue so if an image doesn't successfully fire, we have a chance to pull the log entry out of storage and try again.

Duplicate firings are a possibility (the browser could fire without us getting confirmation), so we will probably have to generate a unique ID and de-duplicate on the server.
Comment 1 Ori Livneh 2012-12-19 09:36:09 UTC
The localStorage API is synchronous, so it's possible to reliably set an item in localStorage in an on click handler without having to resort to voodoo.

(According to http://www.nczonline.net/blog/2012/03/07/in-defense-of-localstorage/, IE 8's implementation is asynchronous. But I'm sure we could hack around it somehow.)

There are serious questions to answer, though:

* What if the link navigates away from Wikipedia entirely? You might simply assume that the user will come back eventually, and you'll fire the event then. But then the server timestamp is no longer an accurate indicator of when an event took place. We'd have to reintroduce client-side timestamps, I think.

* Does it make sense to implement this in ext.eventLogging.core.js? We could rewrite mw.eventLog.logEvent to write to localStorage by default, and poll it asynchronously using setInterval to actually log events to the server.

Ideas?
Comment 2 Ori Livneh 2013-01-10 11:21:19 UTC
If we had CORS, we could use $.ajax( { asynchronous: false, ... } ).
Comment 3 Ori Livneh 2013-01-10 19:49:11 UTC
Batching events will make us much more reliant on client-side timestamps and thus open up a can of worms. A robust alternative to $.fn.stall is needed, but localStorage is just one possible approach. I'm going to create a separate bug for $.fn.stall and close this as WONTFIX for now.
Comment 4 Ori Livneh 2013-01-10 19:50:43 UTC
(In reply to comment #3)
> I'm going to create a separate bug for $.fn.stall and
> close this as WONTFIX for now.

Ugh, I changed my mind about this but submitted the comment by accident when I changed the title. This should be the bug for tracking synchronous event logging.
Comment 5 Ori Livneh 2013-02-22 23:26:54 UTC
I confirmed that $.ajax({ async: false }) requests work. You only need CORS if you want to handle the response, which we don't care about: we only care that the request is made against bits, which it is.
Comment 6 Matthew Flaschen 2013-07-30 18:44:17 UTC
I don't think we really want synchronous network requests.  They block the entire event loop and can cause other problems (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests?redirectlocale=en-US&redirectslug=DOM%2FXMLHttpRequest%2FSynchronous_and_Asynchronous_Requests).

I think we can distinguish between persistent logging and synchronous logging.  'Persistent' means it will try again until it's logged successfully (or it reaches a maximum number of attempts).  'Synchronous' means it logs, blocking the event loop, immediately when logEvent is called.
Comment 7 Ori Livneh 2013-09-02 19:39:40 UTC
The Beacon API proposal from the W3C Web Performance Working Group, published last month, takes a stab at solving the exact problem that this bug describes: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/Beacon/Overview.html

The proposal itself is just that -- a proposal. I don't think any browser vendors implement it yet. But it's highly useful, because it tells us that this is indeed a thorny problem, not just something we haven't figured out, and because it gives a concise overview of existing techniques & their limitations. This part of the proposal is worth quoting in full:


"User agents will typically ignore asynchronous XMLHttpRequests made in an unload handler. To solve this problem, analytics and diagnostics code will typically make a synchronous XMLHttpRequest in an unload or beforeunload handler to submit the data. The synchronous XMLHttpRequest forces the user agent to delay unloading the document, and makes the next navigation appear to be slower. There is little the next page can do to avoid this perception of poor page load performance.

"In addition, there are other poor patterns used to ensure that data is submitted. One such pattern to delay the unload in order to submit data is to create an Image element and set its src attribute within the unload handler. As most user agents will delay the unload to complete the pending image load, data can be submitted during the unload. Another technique is to create a no-op loop for several seconds within the unload handler to delay the unload and submit data to a server.

"Not only do these techniques represent poor coding patterns, some of them are unreliable and also result in the perception of poor page load performance for the next navigation."
Comment 8 Andre Klapper 2014-02-26 12:53:39 UTC
[moving from MediaWiki extensions to Analytics product - see bug 61946]
Comment 9 Matthew Flaschen 2014-04-25 21:29:59 UTC
Bumping the priority on this and renaming somewhat, since this seems to be the preferred approach (for performance reasons) for moving forward on the link click problem.  See discussion at https://bugzilla.wikimedia.org/show_bug.cgi?id=52287 .

I propose using jQuery jStorage, which is a localStorage wrapper (already in core) with support for globalStorage and IE userData as a fallback.
Comment 10 Matthew Flaschen 2014-04-25 21:34:11 UTC
(In reply to Matthew Flaschen from comment #9)
> I propose using jQuery jStorage, which is a localStorage wrapper (already in
> core) with support for globalStorage and IE userData as a fallback.

To be clearer, jStorage has support for globalStorage and userData too.  We wouldn't need to add that.
Comment 11 Krinkle 2014-07-21 20:26:24 UTC
(In reply to Ori Livneh from comment #7)
> The Beacon API proposal from the W3C Web Performance Working Group,
> published last month, takes a stab at solving the exact problem that this
> bug describes:
> https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/Beacon/Overview.html
> 
> The proposal itself is just that -- a proposal. I don't think any browser
> vendors implement it yet.

Firefox landed it recently in stable:
https://developer.mozilla.org/en-US/docs/Web/API/navigator.sendBeacon
https://developer.mozilla.org/en-US/Firefox/Releases/31

Chrome landed it in canary (Chrome 37), soon to be in stable:
https://code.google.com/p/chromium/issues/detail?id=360603
Comment 12 Matthew Flaschen 2014-08-05 03:32:54 UTC
(In reply to Krinkle from comment #11)
> Firefox landed it recently in stable:
> https://developer.mozilla.org/en-US/docs/Web/API/navigator.sendBeacon
> https://developer.mozilla.org/en-US/Firefox/Releases/31
> 
> Chrome landed it in canary (Chrome 37), soon to be in stable:
> https://code.google.com/p/chromium/issues/detail?id=360603

This seems like a good choice then.  We can use sendBeacon when available, and use jStorage when it's not.  However, ideally, the issue with localStorage being used up should be solved first, or the fallback will be less effective (or have to use cookies).
Comment 13 Gerrit Notification Bot 2014-10-29 10:48:35 UTC
Change 162194 had a related patch set uploaded by Prtksxna:
Add an experimental function to log events using the sendBeacon API.

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

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links