Fix: Save user options only once when Advanced Mode is toggled
Currently, when a user toggles the Advanced Mode preference on or off
in Special:MobileOptions on a wiki with WikimediaEvents enabled, a
PrefUpdate event is emitted reflecting the change to mf_amc_optin,
along with a duplicate of the same event and a number of spurious
additional PrefUpdate events. This can be easily reproduced on the
Beta Cluster by tailing /srv/log/eventlogging/client-side-events.log
on deployment-eventlog05 while toggling the Advanced Mode switch.
When Special:MobileOptions is loaded, the UserOptionsManager service
loads the current user's preferences from the database and caches
them. When UserOptionsManager::saveOptions is called, the user's
current preferences and the cached originals are passed to the
UserSaveOptions hook for processing by other extensions including
WikimediaEvents; the database is updated to reflect changes to
stored values; and the cache of originals is cleared. This appears
to reflect an assumption that saveOptions will not be called again in
the course of the same web request.
When the Advanced Mode switch is toggled, two separate deferred
updates are created to save updated preferences to the database: one
each for enableAMC and enableBeta. The first update is processed as
expected, and a PrefUpdate event is appropriately emitted. When the
second deferred update is processed, the user's current preferences
are compared against an empty list of originals as a result of the
first update when assessing changed preferences for PrefUpdate event
creation. This results in PrefUpdate events being improperly emitted
for every preference tracked in PrefUpdateInstrumentation for which
the user has a value defined. However, there are no improper changes
to the user's preferences since the new values are ultimately
checked against those stored in the database.
This change fixes the issue of spurious PrefUpdate event creation by
collecting both preference updates into a single User::saveSettings
call in a single deferred update.