EBernhardson has uploaded a new change for review.

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

Change subject: Re-deploy WME changes after deploying necessary CirrusSearch 
change first
......................................................................

Re-deploy WME changes after deploying necessary CirrusSearch change first

Revert "Revert "Rename search.js -> searchSatisfaction.js""
Revert "Revert "Move Schema:Search from CirrusSearch""
Revert "Revert "Refactor search.js to only load deps for users in test""

This reverts commit 43544897a443bd031179d7ba9a472b90f045d7ce.
This reverts commit ab73647d88246259d720bdb9f882d58c99bc0a61.
This reverts commit 2160b92b0160db81314042bab64b6214590ba914.

Change-Id: I205f41d5cecd425235bc718a5efa8f68e2561798
---
M WikimediaEvents.php
M modules/ext.wikimediaEvents.search.js
A modules/ext.wikimediaEvents.searchSatisfaction.js
3 files changed, 169 insertions(+), 105 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikimediaEvents 
refs/changes/93/248893/1

diff --git a/WikimediaEvents.php b/WikimediaEvents.php
index 2a0c0c3..a304498 100644
--- a/WikimediaEvents.php
+++ b/WikimediaEvents.php
@@ -95,6 +95,11 @@
                'schema'   => 'GeoFeatures',
                'revision' => 12914994,
        ),
+       'schema.Search' => array(
+               'class'    => 'ResourceLoaderSchemaModule',
+               'schema'   => 'Search',
+               'revision' => 11670541,
+       ),
        'ext.wikimediaEvents' => array(
                // Loaded globally for all users (including logged-out)
                // Don't remove if empty!
@@ -102,11 +107,12 @@
                        'ext.wikimediaEvents.resourceloader.js',
                        'ext.wikimediaEvents.searchSuggest.js',
                        'ext.wikimediaEvents.statsd.js',
+                       'ext.wikimediaEvents.searchSatisfaction.js',
                        'ext.wikimediaEvents.search.js',
                ),
                'dependencies' => array(
-                       'mediawiki.user', // needed by searchSuggest.js
-                       'mediawiki.Uri', // needed by search.js
+                       'mediawiki.user', // needed by search.js, 
searchSuggest.js
+                       'mediawiki.Uri', // needed by searchSatisfaction.js
                ),
                'localBasePath' => __DIR__ . '/modules',
                'remoteExtPath' => 'WikimediaEvents/modules',
diff --git a/modules/ext.wikimediaEvents.search.js 
b/modules/ext.wikimediaEvents.search.js
index ac173f9..0edd61b 100644
--- a/modules/ext.wikimediaEvents.search.js
+++ b/modules/ext.wikimediaEvents.search.js
@@ -1,111 +1,58 @@
-/*!
- * Javacsript module for measuring internal search bounce rate and dwell time.
- *
- * @license GNU GPL v2 or later
- * @author Erik Bernhardson <[email protected]>
- */
-( function ( mw, $, undefined ) {
-       var isSearchResultPage = mw.config.get( 'wgIsSearchResultPage' ),
-               uri = new mw.Uri( location.href ),
-               cameFromSearchResult = uri.query.wprov === 'cirrus';
+/*global mw:true */
+( function ( $ ) {
+       'use strict';
 
-       function oneIn( populationSize ) {
-               return Math.floor( Math.random() * populationSize ) === 0;
-       }
+       var defaults, depsPromise, sessionStartTime,
+               getRandomToken = function () {
+                       return mw.user.generateRandomSessionId() + ( new Date() 
).getTime().toString();
+               },
+               oneIn = function ( populationSize ) {
+                       var rand = parseInt( 
mw.user.generateRandomSessionId().slice( 0, 13 ), 16 );
+                       return rand % populationSize === 0;
+               },
+               isLoggingEnabled = mw.config.get( 
'wgCirrusSearchEnableSearchLogging' );
 
-       if ( cameFromSearchResult ) {
-               // cleanup the location bar in supported browsers
-               if ( window.history.replaceState ) {
-                       delete uri.query.wprov;
-                       window.history.replaceState( {}, '', uri.toString() );
-               }
-       } else if ( !isSearchResultPage ) {
+       // For 1 in a 1000 users the metadata about interaction
+       // with the search form (absent search terms) is event logged.
+       // See https://meta.wikimedia.org/wiki/Schema:Search
+       if ( !isLoggingEnabled || !oneIn( 1000 ) ) {
                return;
        }
 
-       mw.loader.using( [
-               'jquery.jStorage',
-               'mediawiki.user',
-               'ext.eventLogging',
-               'schema.TestSearchSatisfaction2'
-       ] ).then( function () {
-               var searchSessionId = $.jStorage.get( 'searchSessionId' ),
-                       sessionLifetimeMs = 10 * 60 * 1000,
-                       checkinTimes = [ 10, 20, 30, 40, 50, 60, 90, 120, 150, 
180, 210, 240, 300, 360, 420 ],
-                       pageId = mw.user.generateRandomSessionId(),
-                       logEvent = function ( action, checkinTime ) {
-                               var evt = {
-                                               // searchResultPage, visitPage 
or checkin
-                                               action: action,
-                                               // identifies a single user 
performing searches within
-                                               // a limited time span.
-                                               searchSessionId: 
searchSessionId,
-                                               // used to correlate actions 
that happen on the same
-                                               // page. Otherwise a user 
opening multiple search results
-                                               // in tabs would make their 
events overlap and the dwell
-                                               // time per page uncertain.
-                                               pageId: pageId,
-                                               // we noticed a number of 
events get sent multiple
-                                               // times from javascript, 
especially when using sendBeacon.
-                                               // This logId allows for later 
deduplication
-                                               logId: 
mw.user.generateRandomSessionId()
-                                       };
-                               if ( checkinTime !== undefined ) {
-                                       evt.checkin = checkinTime;
-                               }
-                               mw.eventLog.logEvent( 
'TestSearchSatisfaction2', evt );
-                       },
-                       updateHref = function () {
-                               var uri = new mw.Uri( this.href );
-                               // try to not add our query param to 
unnecessary places
-                               if ( uri.path.substr( 0, 6 ) === '/wiki/' ) {
-                                       uri.query.wprov = 'cirrus';
-                                       this.href = uri.toString();
-                               }
-                       };
+       depsPromise = mw.loader.using( [
+               'schema.Search',
+               'ext.eventLogging'
+       ] );
 
-               if ( searchSessionId === 'rejected' ) {
-                       // User was previously rejected or timed out
-                       return;
-               } else if ( searchSessionId ) {
-                       // User was previously chosen to participate in the 
test.
-                       // When a new search is performed reset the session 
lifetime.
-                       if ( isSearchResultPage ) {
-                               $.jStorage.setTTL( 'searchSessionId', 
sessionLifetimeMs );
-                       }
-               } else if (
-                       // Most likely this means the users search session 
timed out.
-                       !isSearchResultPage ||
-                       // user was not chosen in a sampling of search results
-                       !oneIn( 200 )
-               ) {
-                       $.jStorage.set( 'searchSessionId', 'rejected', { TTL: 2 
* sessionLifetimeMs } );
-                       return;
-               } else {
-                       // User was chosen to participate in the test and does 
not yet
-                       // have a search session id, generate one.
-                       searchSessionId = mw.user.generateRandomSessionId();
-                       $.jStorage.set( 'searchSessionId', searchSessionId, { 
TTL: sessionLifetimeMs } );
-                       // If storage is full jStorage will fail to store our 
session
-                       // identifier and it will come back null.  In that case 
we
-                       // can't reliably correlate events from the SERP to the 
target
-                       // pages.
-                       if ( $.jStorage.get( 'searchSessionId' ) !== 
searchSessionId ) {
-                               return;
-                       }
+       defaults = {
+               platform: 'desktop',
+               userSessionToken: getRandomToken(),
+               searchSessionToken: getRandomToken()
+       };
+
+       mw.trackSubscribe( 'mediawiki.searchSuggest', function ( topic, data ) {
+               var loggingData = {
+                       action: data.action
+               };
+
+               if ( data.action === 'session-start' ) {
+                       // update session token if it's a new search
+                       defaults.searchSessionToken = getRandomToken();
+                       sessionStartTime = this.timeStamp;
+               } else if ( data.action === 'impression-results' ) {
+                       loggingData.numberOfResults = data.numberOfResults;
+                       loggingData.resultSetType = data.resultSetType;
+                       loggingData.timeToDisplayResults = Math.round( 
this.timeStamp - sessionStartTime );
+               } else if ( data.action === 'click-result' ) {
+                       loggingData.clickIndex = data.clickIndex;
+                       loggingData.numberOfResults = data.numberOfResults;
+               } else if ( data.action === 'submit-form' ) {
+                       loggingData.numberOfResults = data.numberOfResults;
                }
-
-               $( '#mw-content-text a:not(.external)' ).each( updateHref );
-
-               if ( isSearchResultPage ) {
-                       logEvent( 'searchResultPage' );
-               } else {
-                       logEvent( 'visitPage' );
-                       $( checkinTimes ).each( function ( _, checkin ) {
-                               setTimeout( function () {
-                                       logEvent( 'checkin', checkin );
-                               }, 1000 * checkin );
-                       } );
-               }
+               loggingData.timeOffsetSinceStart = Math.round( this.timeStamp - 
sessionStartTime ) ;
+               $.extend( loggingData, defaults );
+               depsPromise.then( function () {
+                       mw.eventLog.logEvent( 'Search', loggingData );
+               } );
        } );
-}( mediaWiki, jQuery ) );
+}( jQuery ) );
diff --git a/modules/ext.wikimediaEvents.searchSatisfaction.js 
b/modules/ext.wikimediaEvents.searchSatisfaction.js
new file mode 100644
index 0000000..ac173f9
--- /dev/null
+++ b/modules/ext.wikimediaEvents.searchSatisfaction.js
@@ -0,0 +1,111 @@
+/*!
+ * Javacsript module for measuring internal search bounce rate and dwell time.
+ *
+ * @license GNU GPL v2 or later
+ * @author Erik Bernhardson <[email protected]>
+ */
+( function ( mw, $, undefined ) {
+       var isSearchResultPage = mw.config.get( 'wgIsSearchResultPage' ),
+               uri = new mw.Uri( location.href ),
+               cameFromSearchResult = uri.query.wprov === 'cirrus';
+
+       function oneIn( populationSize ) {
+               return Math.floor( Math.random() * populationSize ) === 0;
+       }
+
+       if ( cameFromSearchResult ) {
+               // cleanup the location bar in supported browsers
+               if ( window.history.replaceState ) {
+                       delete uri.query.wprov;
+                       window.history.replaceState( {}, '', uri.toString() );
+               }
+       } else if ( !isSearchResultPage ) {
+               return;
+       }
+
+       mw.loader.using( [
+               'jquery.jStorage',
+               'mediawiki.user',
+               'ext.eventLogging',
+               'schema.TestSearchSatisfaction2'
+       ] ).then( function () {
+               var searchSessionId = $.jStorage.get( 'searchSessionId' ),
+                       sessionLifetimeMs = 10 * 60 * 1000,
+                       checkinTimes = [ 10, 20, 30, 40, 50, 60, 90, 120, 150, 
180, 210, 240, 300, 360, 420 ],
+                       pageId = mw.user.generateRandomSessionId(),
+                       logEvent = function ( action, checkinTime ) {
+                               var evt = {
+                                               // searchResultPage, visitPage 
or checkin
+                                               action: action,
+                                               // identifies a single user 
performing searches within
+                                               // a limited time span.
+                                               searchSessionId: 
searchSessionId,
+                                               // used to correlate actions 
that happen on the same
+                                               // page. Otherwise a user 
opening multiple search results
+                                               // in tabs would make their 
events overlap and the dwell
+                                               // time per page uncertain.
+                                               pageId: pageId,
+                                               // we noticed a number of 
events get sent multiple
+                                               // times from javascript, 
especially when using sendBeacon.
+                                               // This logId allows for later 
deduplication
+                                               logId: 
mw.user.generateRandomSessionId()
+                                       };
+                               if ( checkinTime !== undefined ) {
+                                       evt.checkin = checkinTime;
+                               }
+                               mw.eventLog.logEvent( 
'TestSearchSatisfaction2', evt );
+                       },
+                       updateHref = function () {
+                               var uri = new mw.Uri( this.href );
+                               // try to not add our query param to 
unnecessary places
+                               if ( uri.path.substr( 0, 6 ) === '/wiki/' ) {
+                                       uri.query.wprov = 'cirrus';
+                                       this.href = uri.toString();
+                               }
+                       };
+
+               if ( searchSessionId === 'rejected' ) {
+                       // User was previously rejected or timed out
+                       return;
+               } else if ( searchSessionId ) {
+                       // User was previously chosen to participate in the 
test.
+                       // When a new search is performed reset the session 
lifetime.
+                       if ( isSearchResultPage ) {
+                               $.jStorage.setTTL( 'searchSessionId', 
sessionLifetimeMs );
+                       }
+               } else if (
+                       // Most likely this means the users search session 
timed out.
+                       !isSearchResultPage ||
+                       // user was not chosen in a sampling of search results
+                       !oneIn( 200 )
+               ) {
+                       $.jStorage.set( 'searchSessionId', 'rejected', { TTL: 2 
* sessionLifetimeMs } );
+                       return;
+               } else {
+                       // User was chosen to participate in the test and does 
not yet
+                       // have a search session id, generate one.
+                       searchSessionId = mw.user.generateRandomSessionId();
+                       $.jStorage.set( 'searchSessionId', searchSessionId, { 
TTL: sessionLifetimeMs } );
+                       // If storage is full jStorage will fail to store our 
session
+                       // identifier and it will come back null.  In that case 
we
+                       // can't reliably correlate events from the SERP to the 
target
+                       // pages.
+                       if ( $.jStorage.get( 'searchSessionId' ) !== 
searchSessionId ) {
+                               return;
+                       }
+               }
+
+               $( '#mw-content-text a:not(.external)' ).each( updateHref );
+
+               if ( isSearchResultPage ) {
+                       logEvent( 'searchResultPage' );
+               } else {
+                       logEvent( 'visitPage' );
+                       $( checkinTimes ).each( function ( _, checkin ) {
+                               setTimeout( function () {
+                                       logEvent( 'checkin', checkin );
+                               }, 1000 * checkin );
+                       } );
+               }
+       } );
+}( mediaWiki, jQuery ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/248893
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I205f41d5cecd425235bc718a5efa8f68e2561798
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikimediaEvents
Gerrit-Branch: wmf/1.27.0-wmf.3
Gerrit-Owner: EBernhardson <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to