/**
   * Is invoked for the backup of a non-sticky session that was not accessed for the current
   * request.
   */
  protected void onBackupWithoutLoadedSession(
      @Nonnull final String sessionId,
      @Nonnull final String requestId,
      @Nonnull final BackupSessionService backupSessionService) {

    if (!_sessionIdFormat.isValid(sessionId)) {
      return;
    }

    try {

      final long start = System.currentTimeMillis();

      final String validityKey = _sessionIdFormat.createValidityInfoKeyName(sessionId);
      final SessionValidityInfo validityInfo = loadSessionValidityInfoForValidityKey(validityKey);
      if (validityInfo == null) {
        _log.warn("Found no validity info for session id " + sessionId);
        return;
      }

      final int maxInactiveInterval = validityInfo.getMaxInactiveInterval();
      final byte[] validityData =
          encode(maxInactiveInterval, System.currentTimeMillis(), System.currentTimeMillis());
      // fix for #88, along with the change in session.getMemcachedExpirationTimeToSet
      final int expiration = maxInactiveInterval <= 0 ? 0 : maxInactiveInterval;
      final Future<Boolean> validityResult =
          _memcached.set(validityKey, toMemcachedExpiration(expiration), validityData);
      if (!_manager.isSessionBackupAsync()) {
        validityResult.get(_manager.getSessionBackupTimeout(), TimeUnit.MILLISECONDS);
      }

      /*
       * - ping session
       * - ping session backup
       * - save validity backup
       */
      final Callable<?> backupSessionTask =
          new OnBackupWithoutLoadedSessionTask(
              sessionId, _storeSecondaryBackup, validityKey, validityData, maxInactiveInterval);
      _executor.submit(backupSessionTask);

      if (_log.isDebugEnabled()) {
        _log.debug("Stored session validity info for session " + sessionId);
      }

      _stats.registerSince(NON_STICKY_ON_BACKUP_WITHOUT_LOADED_SESSION, start);

    } catch (final Throwable e) {
      _log.warn("An error when trying to load/update validity info.", e);
    }
  }
  /**
   * Invoked after a non-sticky session is loaded from memcached, can be used to update some session
   * fields based on separately stored information (e.g. session validity info).
   *
   * @param lockStatus the {@link LockStatus} that was returned from {@link
   *     #onBeforeLoadFromMemcached(String)}.
   */
  protected void onAfterLoadFromMemcached(
      @Nonnull final MemcachedBackupSession session, @Nullable final LockStatus lockStatus) {
    session.setLockStatus(lockStatus);

    final long start = System.currentTimeMillis();
    final SessionValidityInfo info = loadSessionValidityInfo(session.getIdInternal());
    if (info != null) {
      _stats.registerSince(NON_STICKY_AFTER_LOAD_FROM_MEMCACHED, start);
      session.setLastAccessedTimeInternal(info.getLastAccessedTime());
      session.setThisAccessedTimeInternal(info.getThisAccessedTime());
    } else {
      _log.warn("No validity info available for session " + session.getIdInternal());
    }
  }