HomePhabricator

Improvements to user preferences fetching/saving

Description

Improvements to user preferences fetching/saving

Status quo

When saving user preferences, we want to lock the rows to avoid
accidentally overriding a concurrent options update. So usually
what extensions do is:

$value = $mngr->getOption( 'option', ..., READ_LOCKING );
if ( $value !== 'new_value' ) {

$mngr->setOption( 'option', 'new_value' );
$mngr->saveOptions()

}

Previously for extra caution we've ignored all caches in options
manager if >= READ_LOCKING flags were passed. This resulted in
re-reading all the options multiple times. At worst, 3 times:

  1. If READ_NORMAL read was made for update - that's once,
  2. On setOption, one more read, forcefully from primary
  3. On saveOptions, one more read from primary, non-locking,

to figure out which option keys need to be deleted.

Also, READ_LOCKING was not used where it clearly had to be used,
for example right before the update. This was trying to fix any
kind of error on part of the manager clients, unsuccessfully so.

New approach

  1. Cache modified user options separately from originals and merge

them on demand. This means when refetching originals with LOCKING
we don't wipe out all modifications made to the cache with setOption.
Extra bonus - we no longer need to load all options to set an option.

  1. Split the originals cache into 2 layers - one for stuff that

comes from DB directly, and one with applied normalizations and
whatever hooks modify. This let's us avoid refetching DB options
after we save them, but still let's the hooks execute on newly set
options after they're saved.

  1. Cache options with all query flags. This is a bit controversial, but

ideally LOCKING flags will be applied on options fetch right before
they are saved. We have to re-read options with LOCKING in saveOptions
to avoid races, but if the caller did 'getOption( ..., LOCKING),
setOption(), save()' we will not need to re-select with LOCKING again.

Bug: T280220
Change-Id: Ibed2789f5260b725fd806b4470631aa30d814ce6

Details

Provenance
PcheloloAuthored on Jun 11 2021, 6:48 PM
LegoktmCommitted on Jun 23 2021, 11:56 PM
Parents
rMW4c85648f323b: Merge "Remove User from password policy check interfaces"
Branches
Unknown
Tags
Unknown
ChangeId
Ibed2789f5260b725fd806b4470631aa30d814ce6