87 foreach ( $entities as $entity ) {
88 $entitiesByKey[$this->getStoreKey( $entity )] = $entity;
91 $blobsByKey = $this->stash->getMulti( array_keys( $entitiesByKey ) );
94 foreach ( $entitiesByKey as $key => $entity ) {
95 $blob = $blobsByKey[$key] ??
null;
96 $data = is_string( $blob ) ? json_decode( $blob,
true ) :
null;
98 $data[self::KEY_PATHS] ?? [],
99 $data[self::KEY_AS_OF] ??
null
107 $hasPendingUpdate = (bool)$this->updateBuffer;
109 foreach ( $pathByEntity as $entity => $paths ) {
119 if ( !$hasPendingUpdate ) {
120 DeferredUpdates::addCallableUpdate(
function () {
122 $this->updateBuffer = [];
127 $cache = MediaWikiServices::getInstance()
128 ->getObjectCacheFactory()->getLocalClusterInstance();
129 foreach ( $updatesByEntity as $entity => $update ) {
130 $lockKey = $cache->makeKey(
'rl-deps', $entity );
131 $scopeLocks[$entity] = $cache->getScopedLock( $lockKey, 0 );
132 if ( !$scopeLocks[$entity] ) {
138 $entitiesUnreg[] = $entity;
140 $depsByEntity[$entity] = $update;
144 foreach ( $depsByEntity as $entity => $data ) {
145 if ( !is_array( $data[self::KEY_PATHS] ) || !is_int( $data[self::KEY_AS_OF] ) ) {
146 throw new InvalidArgumentException(
"Invalid entry for '$entity'" );
150 $data[
self::KEY_PATHS] = array_values( array_unique( $data[self::KEY_PATHS] ) );
151 sort( $data[self::KEY_PATHS], SORT_STRING );
153 $blob = json_encode( $data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
155 $blobsByKey[$this->getStoreKey( $entity )] = $blob;
159 $this->stash->setMulti( $blobsByKey, self::RL_MODULE_DEP_TTL, BagOStuff::WRITE_BACKGROUND );
162 $this->
remove( $entitiesUnreg );