public void saveValidityBackup() { final String backupValidityKey = _sessionIdFormat.createBackupKey(_validityKey); final int maxInactiveInterval = _session.getMaxInactiveInterval(); // fix for #88, along with the change in session.getMemcachedExpirationTimeToSet final int expiration = maxInactiveInterval <= 0 ? 0 : maxInactiveInterval; _memcached.set(backupValidityKey, toMemcachedExpiration(expiration), _validityData); }
static byte[] serializeSessionFields(final MemcachedBackupSession session) { final byte[] idData = serializeId(session.getIdInternal()); final byte[] principalData = session.getPrincipal() != null ? serializePrincipal(session.getPrincipal()) : null; final int principalDataLength = principalData != null ? principalData.length : 0; final int sessionFieldsDataLength = 2 // short value for the version // the following might change with other versions, refactoring needed then + 2 // short value that stores the dataLength + NUM_BYTES // bytes that store all session attributes but the id + 2 // short value that stores the idData length + idData.length // the number of bytes for the id + 2 // short value for the authType + 2 // short value that stores the principalData length + principalDataLength; // the number of bytes for the principal final byte[] data = new byte[sessionFieldsDataLength]; int idx = 0; idx = encodeNum(CURRENT_VERSION, data, idx, 2); idx = encodeNum(sessionFieldsDataLength, data, idx, 2); idx = encodeNum(session.getCreationTimeInternal(), data, idx, 8); idx = encodeNum(session.getLastAccessedTimeInternal(), data, idx, 8); idx = encodeNum(session.getMaxInactiveInterval(), data, idx, 4); idx = encodeBoolean(session.isNewInternal(), data, idx); idx = encodeBoolean(session.isValidInternal(), data, idx); idx = encodeNum(session.getThisAccessedTimeInternal(), data, idx, 8); idx = encodeNum(session.getLastBackupTime(), data, idx, 8); idx = encodeNum(idData.length, data, idx, 2); idx = copy(idData, data, idx); idx = encodeNum(AuthType.valueOfValue(session.getAuthType()).getId(), data, idx, 2); idx = encodeNum(principalDataLength, data, idx, 2); copy(principalData, data, idx); return data; }
/** * Is invoked after the backup of the session is initiated, it's represented by the provided * backupResult. The requestId is identifying the request. */ protected void onAfterBackupSession( @Nonnull final MemcachedBackupSession session, final boolean backupWasForced, @Nonnull final Future<BackupResult> result, @Nonnull final String requestId, @Nonnull final BackupSessionService backupSessionService) { if (!_sessionIdFormat.isValid(session.getIdInternal())) { return; } try { final long start = System.currentTimeMillis(); final int maxInactiveInterval = session.getMaxInactiveInterval(); final byte[] validityData = encode( maxInactiveInterval, session.getLastAccessedTimeInternal(), session.getThisAccessedTimeInternal()); final String validityKey = _sessionIdFormat.createValidityInfoKeyName(session.getIdInternal()); // 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()) { // TODO: together with session backup wait not longer than sessionBackupTimeout. // Details: Now/here we're waiting the whole session backup timeout, even if (perhaps) some // time // was spent before when waiting for session backup result. // For sync session backup it would be better to set both the session data and // validity info and afterwards wait for both results (but in sum no longer than // sessionBackupTimeout) validityResult.get(_manager.getSessionBackupTimeout(), TimeUnit.MILLISECONDS); } if (_log.isDebugEnabled()) { _log.debug("Stored session validity info for session " + session.getIdInternal()); } /* The following task are performed outside of the request thread (includes waiting for the backup result): * - ping session if the backup was skipped (depends on the backup result) * - save secondary session backup if session was modified (backup not skipped) * - ping secondary session backup if the backup was skipped * - save secondary validity backup */ final boolean pingSessionIfBackupWasSkipped = !backupWasForced; final boolean performAsyncTasks = pingSessionIfBackupWasSkipped || _storeSecondaryBackup; if (performAsyncTasks) { final Callable<?> backupSessionTask = new OnAfterBackupSessionTask( session, result, pingSessionIfBackupWasSkipped, backupSessionService, _storeSecondaryBackup, validityKey, validityData); _executor.submit(backupSessionTask); } _stats.registerSince(NON_STICKY_AFTER_BACKUP, start); } catch (final Throwable e) { _log.warn("An error occurred during onAfterBackupSession.", e); } }