public Future<BackupResult> backupSession( final String sessionId, final boolean sessionIdChanged, final String requestId ) {
        if ( !_enabled.get() ) {
            return new SimpleFuture<BackupResult>( BackupResult.SKIPPED );
        }

        final MemcachedBackupSession msmSession = _manager.getSessionInternal( sessionId );
        if ( msmSession == null ) {
            if(_log.isDebugEnabled())
                _log.debug( "No session found in session map for " + sessionId );
            if ( !_sticky ) {
                // Issue 116/137: Only notify the lockingStrategy if the session was loaded and has not been removed/invalidated
                if(!_invalidSessionsCache.containsKey(sessionId)) {
                    _lockingStrategy.onBackupWithoutLoadedSession( sessionId, requestId, _backupSessionService );
                }
            }
            return new SimpleFuture<BackupResult>( BackupResult.SKIPPED );
        }

        if ( !msmSession.isValidInternal() ) {
            if(_log.isDebugEnabled())
                _log.debug( "Non valid session found in session map for " + sessionId );
            return new SimpleFuture<BackupResult>( BackupResult.SKIPPED );
        }

        if ( !_sticky ) {
            synchronized (_manager.getSessionsInternal()) {
                // if another thread in the meantime retrieved the session
                // we must not remove it as this would case session data loss
                // for the other request
                if ( msmSession.releaseReference() > 0 ) {
                    if(_log.isDebugEnabled())
                        _log.debug( "Session " + sessionId + " is still used by another request, skipping backup and (optional) lock handling/release." );
                    return new SimpleFuture<BackupResult>( BackupResult.SKIPPED );
                }
                msmSession.passivate();
                _manager.removeInternal( msmSession, false );
            }
        }

        final boolean force = sessionIdChanged || msmSession.isSessionIdChanged() || !_sticky && (msmSession.getSecondsSinceLastBackup() >= msmSession.getMaxInactiveInterval());
        final Future<BackupResult> result = _backupSessionService.backupSession( msmSession, force );

        if ( !_sticky ) {
            _lockingStrategy.onAfterBackupSession( msmSession, force, result, requestId, _backupSessionService );
        }

        return result;
    }
public Future < BackupResult > backupSession ( final String sessionId , final boolean sessionIdChanged , final String requestId ) { if ( ! _enabled . get ( ) ) { return new SimpleFuture < BackupResult > ( BackupResult . SKIPPED ) ; } final MemcachedBackupSession msmSession = _manager . getSessionInternal ( sessionId ) ; if ( msmSession == null ) { if ( _log . isDebugEnabled ( ) ) _log . debug ( "No session found in session map for " + sessionId ) ; if ( ! _sticky ) { if ( ! _invalidSessionsCache . containsKey ( sessionId ) ) { _lockingStrategy . onBackupWithoutLoadedSession ( sessionId , requestId , _backupSessionService ) ; } } return new SimpleFuture < BackupResult > ( BackupResult . SKIPPED ) ; } if ( ! msmSession . isValidInternal ( ) ) { if ( _log . isDebugEnabled ( ) ) _log . debug ( "Non valid session found in session map for " + sessionId ) ; return new SimpleFuture < BackupResult > ( BackupResult . SKIPPED ) ; } if ( ! _sticky ) { synchronized ( _manager . getSessionsInternal ( ) ) { if ( msmSession . releaseReference ( ) > 0 ) { if ( _log . isDebugEnabled ( ) ) _log . debug ( "Session " + sessionId + " is still used by another request, skipping backup and (optional) lock handling/release." ) ; return new SimpleFuture < BackupResult > ( BackupResult . SKIPPED ) ; } msmSession . passivate ( ) ; _manager . removeInternal ( msmSession , false ) ; } } final boolean force = sessionIdChanged || msmSession . isSessionIdChanged ( ) || ! _sticky && ( msmSession . getSecondsSinceLastBackup ( ) >= msmSession . getMaxInactiveInterval ( ) ) ; final Future < BackupResult > result = _backupSessionService . backupSession ( msmSession , force ) ; if ( ! _sticky ) { _lockingStrategy . onAfterBackupSession ( msmSession , force , result , requestId , _backupSessionService ) ; } return result ; }
Backup the session for the provided session id in memcached if the session was modified or
if the session needs to be relocated. In non-sticky session-mode the session should not be
loaded from memcached for just storing it again but only metadata should be updated.

@param sessionId
the if of the session to backup
@param sessionIdChanged
specifies, if the session id was changed due to a memcached failover or tomcat failover.
@param requestId
the uri of the request for that the session backup shall be performed.

@return a {@link Future} providing the {@link BackupResultStatus}.