Moved ObjectCacheSessionHandler renewal logic to wfSetupSession()

* This should trigger more reliably than the shutdown function
  callback, which is really only there for sanity to make sure
  session close/write happens.

Change-Id: I9a1aa76de121ba8de33b3fa850bd223929fae404
This commit is contained in:
Aaron Schulz 2015-08-03 13:35:50 -07:00 committed by Ori.livneh
parent 127bab6cbd
commit 203d2c9c11
2 changed files with 30 additions and 11 deletions

View file

@ -3461,8 +3461,9 @@ function wfResetSessionID() {
* @param bool $sessionId
*/
function wfSetupSession( $sessionId = false ) {
global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgCookiePath, $wgCookieDomain,
$wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler;
global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgSessionHandler;
global $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly;
if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
ObjectCacheSessionHandler::install();
} elseif ( $wgSessionHandler && $wgSessionHandler != ini_get( 'session.save_handler' ) ) {
@ -3470,6 +3471,7 @@ function wfSetupSession( $sessionId = false ) {
# hasn't already been set to the desired value (that causes errors)
ini_set( 'session.save_handler', $wgSessionHandler );
}
session_set_cookie_params(
0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly );
session_cache_limiter( 'private, must-revalidate' );
@ -3478,9 +3480,14 @@ function wfSetupSession( $sessionId = false ) {
} else {
wfFixSessionID();
}
MediaWiki\suppressWarnings();
session_start();
MediaWiki\restoreWarnings();
if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
ObjectCacheSessionHandler::renewCurrentSession();
}
}
/**

View file

@ -21,6 +21,8 @@
* @ingroup Cache
*/
use MediaWiki\Logger\LoggerFactory;
/**
* Session storage in object cache.
* Used if $wgSessionsInObjectCache is true.
@ -28,9 +30,6 @@
* @ingroup Cache
*/
class ObjectCacheSessionHandler {
const TTL_REFRESH_WINDOW = 600; // refresh if expiring in 10 minutes
/**
* Install a session handler for the current web request
*/
@ -145,20 +144,33 @@ class ObjectCacheSessionHandler {
* See the comment inside ObjectCacheSessionHandler::install for rationale.
*/
static function handleShutdown() {
session_write_close();
}
/**
* Pre-emptive session renewal function
*/
static function renewCurrentSession() {
global $wgObjectCacheSessionExpiry;
// Once a session is at half TTL, renew it
$window = $wgObjectCacheSessionExpiry / 2;
$logger = LoggerFactory::getInstance( 'SessionHandler' );
$now = microtime( true );
// Session are only written in object stores when $_SESSION changes,
// which also renews the TTL ($wgObjectCacheSessionExpiry). If a user
// is active but not causing session data changes, it may suddenly
// as they view a form, blocking the first submission.
// expire as they view a form, blocking the first submission.
// Make a dummy change every so often to avoid this.
if ( !isset( $_SESSION['wsExpiresUnix'] )
|| ( $now + self::TTL_REFRESH_WINDOW ) > isset( $_SESSION['wsExpiresUnix'] )
) {
if ( !isset( $_SESSION['wsExpiresUnix'] ) ) {
$_SESSION['wsExpiresUnix'] = $now + $wgObjectCacheSessionExpiry;
}
session_write_close();
$logger->info( "Set expiry for session " . session_id(), array() );
} elseif ( ( $now + $window ) > $_SESSION['wsExpiresUnix'] ) {
$_SESSION['wsExpiresUnix'] = $now + $wgObjectCacheSessionExpiry;
$logger->info( "Renewed session " . session_id(), array() );
}
}
}