Page MenuHomeWickedGov Phorge

DefaultEventSubmitter.js
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

DefaultEventSubmitter.js

const DEFAULT_EVENTGATE_ORIGIN = 'https://intake-analytics.wikimedia.org';
const DELAYED_SUBMIT_TIMEOUT = 5; // (s)
/**
* @param {string} [origin]
* @return {string}
*/
function getEventGateUrl( origin ) {
const result = new URL( origin || DEFAULT_EVENTGATE_ORIGIN );
result.pathname = '/v1/events';
result.searchParams.set( 'hasty', 'true' );
return result.toString();
}
/**
* The default event submitter used by {@link MetricsClient}.
*
* This event submitter maintains an unbounded internal queue of events, which is drained every
* 5 seconds or when the page is hidden. When the queue is drained, all events in the queue are
* submitted to the event intake service in one request. The request is made using the
* [Navigator: sendBeacon() method][0]. That is, the request is made asynchronously in the
* background by the browser with no indication whether it succeeded.
*
* This event submitter is expected to be used in a browser. As well as the
* [Navigator: sendBeacon() method][0], the event submitter requires the browser to support for the
* [Page Visbility API][1].
*
* [0]: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon
* [1]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
*
* @param {string} [eventGateOrigin] The origin of the EventGate event intake service to send
* events to. `https://intake-analytics.wikimedia.org` by default
* @constructor
*/
function DefaultEventSubmitter( eventGateOrigin ) {
this.eventGateUrl = getEventGateUrl( eventGateOrigin );
/** @type {EventData[]} */
this.events = [];
const eventSubmitter = this;
this.isDocumentUnloading = false;
window.addEventListener( 'pagehide', () => {
eventSubmitter.isDocumentUnloading = true;
} );
window.addEventListener( 'pageshow', () => {
eventSubmitter.isDocumentUnloading = false;
} );
document.addEventListener( 'visibilitychange', () => {
if ( document.hidden ) {
eventSubmitter.doSubmitEvents();
}
} );
this.delayedSubmitTimeoutID = null;
}
/**
* Submits to the event intake service or enqueues the event for submission to the event
* intake service.
*
* @param {EventData} eventData
*/
DefaultEventSubmitter.prototype.submitEvent = function ( eventData ) {
this.events.push( eventData );
if ( this.isDocumentUnloading ) {
this.doSubmitEvents();
} else {
this.doDelayedSubmit();
}
this.onSubmitEvent( eventData );
};
/**
* Submits all queued events to the event intake service immediately and clears the queue.
*
* @ignore
*/
DefaultEventSubmitter.prototype.doSubmitEvents = function () {
if ( this.events.length ) {
try {
navigator.sendBeacon(
this.eventGateUrl,
JSON.stringify( this.events )
);
} catch ( e ) {
// Some browsers throw when sending a beacon to a blocked URL (by an adblocker, for
// example). Some browser extensions remove Navigator#sendBeacon() altogether. See also:
//
// 1. https://phabricator.wikimedia.org/T86680
// 2. https://phabricator.wikimedia.org/T273374
// 3. https://phabricator.wikimedia.org/T308311
//
// Regardless, ignore all errors for now.
//
// TODO (phuedx, 2024/09/09): Instrument this!
}
}
this.events = [];
this.delayedSubmitTimeoutID = null;
};
/**
* Schedules a call to {@link DefaultEventSubmitter#doSubmitEvents} in 5 seconds, if a call is not
* already scheduled.
*
* @ignore
*/
DefaultEventSubmitter.prototype.doDelayedSubmit = function () {
if ( this.delayedSubmitTimeoutID ) {
return;
}
const eventSubmitter = this;
this.delayedSubmitTimeoutID = setTimeout(
() => {
eventSubmitter.doSubmitEvents();
},
DELAYED_SUBMIT_TIMEOUT * 1000
);
};
/**
* Called when an event is enqueued for submission to the event intake service.
*
* @param {EventData} eventData
*/
DefaultEventSubmitter.prototype.onSubmitEvent = function ( eventData ) {
// eslint-disable-next-line no-console
console.info( 'Submitted the following event:', eventData );
};
module.exports = {
DefaultEventSubmitter,
getEventGateUrl
};

File Metadata

Mime Type
text/plain
Expires
Aug 18 2026, 06:26 (7 w, 5 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
32/8f/e82877706a48230ba9a990905c3f
Default Alt Text
DefaultEventSubmitter.js (3 KB)

Event Timeline