Merge "resourceloader: Remove obsolete '$that = $this' closure pattern"
[lhc/web/wiklou.git] / includes / session / SessionBackend.php
index 2a13ed2..fe446e3 100644 (file)
@@ -23,7 +23,7 @@
 
 namespace MediaWiki\Session;
 
-use BagOStuff;
+use CachedBagOStuff;
 use Psr\Log\LoggerInterface;
 use User;
 use WebRequest;
@@ -64,10 +64,8 @@ final class SessionBackend {
        /** @var string Used to detect subarray modifications */
        private $dataHash = null;
 
-       /** @var BagOStuff */
-       private $tempStore;
-       /** @var BagOStuff */
-       private $permStore;
+       /** @var CachedBagOStuff */
+       private $store;
 
        /** @var LoggerInterface */
        private $logger;
@@ -99,14 +97,12 @@ final class SessionBackend {
        /**
         * @param SessionId $id Session ID object
         * @param SessionInfo $info Session info to populate from
-        * @param BagOStuff $tempStore In-process data store
-        * @param BagOStuff $permstore Backend data store for persisted sessions
+        * @param CachedBagOStuff $store Backend data store
         * @param LoggerInterface $logger
         * @param int $lifetime Session data lifetime in seconds
         */
        public function __construct(
-               SessionId $id, SessionInfo $info, BagOStuff $tempStore, BagOStuff $permStore,
-               LoggerInterface $logger, $lifetime
+               SessionId $id, SessionInfo $info, CachedBagOStuff $store, LoggerInterface $logger, $lifetime
        ) {
                $phpSessionHandling = \RequestContext::getMain()->getConfig()->get( 'PHPSessionHandling' );
                $this->usePhpSessionHandling = $phpSessionHandling !== 'disable';
@@ -125,8 +121,7 @@ final class SessionBackend {
 
                $this->id = $id;
                $this->user = $info->getUserInfo() ? $info->getUserInfo()->getUser() : new User;
-               $this->tempStore = $tempStore;
-               $this->permStore = $permStore;
+               $this->store = $store;
                $this->logger = $logger;
                $this->lifetime = $lifetime;
                $this->provider = $info->getProvider();
@@ -135,14 +130,7 @@ final class SessionBackend {
                $this->forceHTTPS = $info->forceHTTPS();
                $this->providerMetadata = $info->getProviderMetadata();
 
-               $key = wfMemcKey( 'MWSession', (string)$this->id );
-               $blob = $tempStore->get( $key );
-               if ( $blob === false ) {
-                       $blob = $permStore->get( $key );
-                       if ( $blob !== false ) {
-                               $tempStore->set( $key, $blob );
-                       }
-               }
+               $blob = $store->get( wfMemcKey( 'MWSession', (string)$this->id ) );
                if ( !is_array( $blob ) ||
                        !isset( $blob['metadata'] ) || !is_array( $blob['metadata'] ) ||
                        !isset( $blob['data'] ) || !is_array( $blob['data'] )
@@ -150,7 +138,11 @@ final class SessionBackend {
                        $this->data = array();
                        $this->dataDirty = true;
                        $this->metaDirty = true;
-                       $this->logger->debug( "SessionBackend $this->id is unsaved, marking dirty in constructor" );
+                       $this->logger->debug(
+                               'SessionBackend "{session}" is unsaved, marking dirty in constructor',
+                               array(
+                                       'session' => $this->id,
+                       ) );
                } else {
                        $this->data = $blob['data'];
                        if ( isset( $blob['metadata']['loggedOut'] ) ) {
@@ -161,8 +153,10 @@ final class SessionBackend {
                        } else {
                                $this->metaDirty = true;
                                $this->logger->debug(
-                                       "SessionBackend $this->id metadata dirty due to missing expiration timestamp"
-                               );
+                                       'SessionBackend "{session}" metadata dirty due to missing expiration timestamp',
+                               array(
+                                       'session' => $this->id,
+                               ) );
                        }
                }
                $this->dataHash = md5( serialize( $this->data ) );
@@ -230,8 +224,11 @@ final class SessionBackend {
                        $this->provider->sessionIdWasReset( $this, $oldId );
                        $this->metaDirty = true;
                        $this->logger->debug(
-                               "SessionBackend $this->id metadata dirty due to ID reset (formerly $oldId)"
-                       );
+                               'SessionBackend "{session}" metadata dirty due to ID reset (formerly "{oldId}")',
+                               array(
+                                       'session' => $this->id,
+                                       'oldId' => $oldId,
+                       ) );
 
                        if ( $restart ) {
                                session_id( (string)$this->id );
@@ -241,8 +238,7 @@ final class SessionBackend {
                        $this->autosave();
 
                        // Delete the data for the old session ID now
-                       $this->tempStore->delete( wfMemcKey( 'MWSession', $oldId ) );
-                       $this->permStore->delete( wfMemcKey( 'MWSession', $oldId ) );
+                       $this->store->delete( wfMemcKey( 'MWSession', $oldId ) );
                }
        }
 
@@ -276,7 +272,11 @@ final class SessionBackend {
                        $this->persist = true;
                        $this->forcePersist = true;
                        $this->metaDirty = true;
-                       $this->logger->debug( "SessionBackend $this->id force-persist due to persist()" );
+                       $this->logger->debug(
+                               'SessionBackend "{session}" force-persist due to persist()',
+                               array(
+                                       'session' => $this->id,
+                       ) );
                        $this->autosave();
                } else {
                        $this->renew();
@@ -301,7 +301,11 @@ final class SessionBackend {
                if ( $this->remember !== (bool)$remember ) {
                        $this->remember = (bool)$remember;
                        $this->metaDirty = true;
-                       $this->logger->debug( "SessionBackend $this->id metadata dirty due to remember-user change" );
+                       $this->logger->debug(
+                               'SessionBackend "{session}" metadata dirty due to remember-user change',
+                               array(
+                                       'session' => $this->id,
+                       ) );
                        $this->autosave();
                }
        }
@@ -358,7 +362,11 @@ final class SessionBackend {
 
                $this->user = $user;
                $this->metaDirty = true;
-               $this->logger->debug( "SessionBackend $this->id metadata dirty due to user change" );
+               $this->logger->debug(
+                       'SessionBackend "{session}" metadata dirty due to user change',
+                       array(
+                               'session' => $this->id,
+               ) );
                $this->autosave();
        }
 
@@ -390,7 +398,11 @@ final class SessionBackend {
                if ( $this->forceHTTPS !== (bool)$force ) {
                        $this->forceHTTPS = (bool)$force;
                        $this->metaDirty = true;
-                       $this->logger->debug( "SessionBackend $this->id metadata dirty due to force-HTTPS change" );
+                       $this->logger->debug(
+                               'SessionBackend "{session}" metadata dirty due to force-HTTPS change',
+                               array(
+                                       'session' => $this->id,
+                       ) );
                        $this->autosave();
                }
        }
@@ -413,8 +425,10 @@ final class SessionBackend {
                        $this->loggedOut = $ts;
                        $this->metaDirty = true;
                        $this->logger->debug(
-                               "SessionBackend $this->id metadata dirty due to logged-out-timestamp change"
-                       );
+                               'SessionBackend "{session}" metadata dirty due to logged-out-timestamp change',
+                               array(
+                                       'session' => $this->id,
+                       ) );
                        $this->autosave();
                }
        }
@@ -441,8 +455,10 @@ final class SessionBackend {
                        $this->providerMetadata = $metadata;
                        $this->metaDirty = true;
                        $this->logger->debug(
-                               "SessionBackend $this->id metadata dirty due to provider metadata change"
-                       );
+                               'SessionBackend "{session}" metadata dirty due to provider metadata change',
+                               array(
+                                       'session' => $this->id,
+                       ) );
                        $this->autosave();
                }
        }
@@ -474,8 +490,11 @@ final class SessionBackend {
                                $data[$key] = $value;
                                $this->dataDirty = true;
                                $this->logger->debug(
-                                       "SessionBackend $this->id data dirty due to addData(): " . wfGetAllCallers( 5 )
-                               );
+                                       'SessionBackend "{session}" data dirty due to addData(): {callers}',
+                                       array(
+                                               'session' => $this->id,
+                                               'callers' => wfGetAllCallers( 5 ),
+                               ) );
                        }
                }
        }
@@ -487,8 +506,11 @@ final class SessionBackend {
        public function dirty() {
                $this->dataDirty = true;
                $this->logger->debug(
-                       "SessionBackend $this->id data dirty due to dirty(): " . wfGetAllCallers( 5 )
-               );
+                       'SessionBackend "{session}" data dirty due to dirty(): {callers}',
+                       array(
+                               'session' => $this->id,
+                               'callers' => wfGetAllCallers( 5 ),
+               ) );
        }
 
        /**
@@ -501,13 +523,19 @@ final class SessionBackend {
                if ( time() + $this->lifetime / 2 > $this->expires ) {
                        $this->metaDirty = true;
                        $this->logger->debug(
-                               "SessionBackend $this->id metadata dirty for renew(): " . wfGetAllCallers( 5 )
-                       );
+                               'SessionBackend "{callers}" metadata dirty for renew(): {callers}',
+                               array(
+                                       'session' => $this->id,
+                                       'callers' => wfGetAllCallers( 5 ),
+                       ) );
                        if ( $this->persist ) {
                                $this->forcePersist = true;
                                $this->logger->debug(
-                                       "SessionBackend $this->id force-persist for renew(): " . wfGetAllCallers( 5 )
-                               );
+                                       'SessionBackend "{session}" force-persist for renew(): {callers}',
+                                       array(
+                                               'session' => $this->id,
+                                               'callers' => wfGetAllCallers( 5 ),
+                               ) );
                        }
                }
                $this->autosave();
@@ -521,13 +549,11 @@ final class SessionBackend {
         * @return \ScopedCallback When this goes out of scope, a save will be triggered
         */
        public function delaySave() {
-               $that = $this;
                $this->delaySave++;
-               $ref = &$this->delaySave;
-               return new \ScopedCallback( function () use ( $that, &$ref ) {
-                       if ( --$ref <= 0 ) {
-                               $ref = 0;
-                               $that->save();
+               return new \ScopedCallback( function () {
+                       if ( --$this->delaySave <= 0 ) {
+                               $this->delaySave = 0;
+                               $this->save();
                        }
                } );
        }
@@ -548,9 +574,12 @@ final class SessionBackend {
        public function save( $closing = false ) {
                if ( $this->provider->getManager()->isUserSessionPrevented( $this->user->getName() ) ) {
                        $this->logger->debug(
-                               "SessionBackend $this->id not saving, " .
-                                       "user {$this->user} was passed to SessionManager::preventSessionsForUser"
-                       );
+                               'SessionBackend "{session}" not saving, user {user} was ' .
+                               'passed to SessionManager::preventSessionsForUser',
+                               array(
+                                       'session' => $this->id,
+                                       'user' => $this->user,
+                       ) );
                        return;
                }
 
@@ -559,8 +588,11 @@ final class SessionBackend {
                $anon = $this->user->isAnon();
                if ( !$anon && !$this->user->getToken( false ) ) {
                        $this->logger->debug(
-                               "SessionBackend $this->id creating token for user {$this->user} on save"
-                       );
+                               'SessionBackend "{session}" creating token for user {user} on save',
+                               array(
+                                       'session' => $this->id,
+                                       'user' => $this->user,
+                       ) );
                        $this->user->setToken();
                        if ( !wfReadOnly() ) {
                                $this->user->saveSettings();
@@ -572,8 +604,13 @@ final class SessionBackend {
                if ( !$this->metaDirty && !$this->dataDirty &&
                        $this->dataHash !== md5( serialize( $this->data ) )
                ) {
-                       $this->logger->debug( "SessionBackend $this->id data dirty due to hash mismatch, " .
-                               "$this->dataHash !== " . md5( serialize( $this->data ) ) );
+                       $this->logger->debug(
+                               'SessionBackend "{session}" data dirty due to hash mismatch, {expected} !== {got}',
+                               array(
+                                       'session' => $this->id,
+                                       'expected' => $this->dataHash,
+                                       'got' => md5( serialize( $this->data ) ),
+                       ) );
                        $this->dataDirty = true;
                }
 
@@ -581,11 +618,15 @@ final class SessionBackend {
                        return;
                }
 
-               $this->logger->debug( "SessionBackend $this->id save: " .
-                       'dataDirty=' . (int)$this->dataDirty . ' ' .
-                       'metaDirty=' . (int)$this->metaDirty . ' ' .
-                       'forcePersist=' . (int)$this->forcePersist
-               );
+               $this->logger->debug(
+                       'SessionBackend "{session}" save: dataDirty={dataDirty} ' .
+                       'metaDirty={metaDirty} forcePersist={forcePersist}',
+                       array(
+                               'session' => $this->id,
+                               'dataDirty' => (int)$this->dataDirty,
+                               'metaDirty' => (int)$this->metaDirty,
+                               'forcePersist' => (int)$this->forcePersist,
+               ) );
 
                // Persist to the provider, if flagged
                if ( $this->persist && ( $this->metaDirty || $this->forcePersist ) ) {
@@ -626,24 +667,15 @@ final class SessionBackend {
                        }
                }
 
-               $this->tempStore->set(
+               $this->store->set(
                        wfMemcKey( 'MWSession', (string)$this->id ),
                        array(
                                'data' => $this->data,
                                'metadata' => $metadata,
                        ),
-                       $metadata['expires']
+                       $metadata['expires'],
+                       $this->persist ? 0 : CachedBagOStuff::WRITE_CACHE_ONLY
                );
-               if ( $this->persist ) {
-                       $this->permStore->set(
-                               wfMemcKey( 'MWSession', (string)$this->id ),
-                               array(
-                                       'data' => $this->data,
-                                       'metadata' => $metadata,
-                               ),
-                               $metadata['expires']
-                       );
-               }
 
                $this->metaDirty = false;
                $this->dataDirty = false;
@@ -658,17 +690,19 @@ final class SessionBackend {
        private function checkPHPSession() {
                if ( !$this->checkPHPSessionRecursionGuard ) {
                        $this->checkPHPSessionRecursionGuard = true;
-                       $ref = &$this->checkPHPSessionRecursionGuard;
-                       $reset = new \ScopedCallback( function () use ( &$ref ) {
-                               $ref = false;
+                       $reset = new \ScopedCallback( function () {
+                               $this->checkPHPSessionRecursionGuard = false;
                        } );
 
                        if ( $this->usePhpSessionHandling && session_id() === '' && PHPSessionHandler::isEnabled() &&
                                SessionManager::getGlobalSession()->getId() === (string)$this->id
                        ) {
-                               $this->logger->debug( "SessionBackend $this->id: Taking over PHP session" );
+                               $this->logger->debug(
+                                       'SessionBackend "{session}" Taking over PHP session',
+                                       array(
+                                               'session' => $this->id,
+                               ) );
                                session_id( (string)$this->id );
-                               \MediaWiki\quietCall( 'session_cache_limiter', 'private, must-revalidate' );
                                \MediaWiki\quietCall( 'session_start' );
                        }
                }