private void updateSession( @Nonnull final MemcachedBackupSession session, @Nonnull final BackupSessionService backupSessionService ) throws InterruptedException { final Future<BackupResult> result = backupSessionService.backupSession( session, true ); try { if ( result.get().getStatus() != BackupResultStatus.SUCCESS ) { _log.warn( "Update for session (after unsuccessful ping) did not return SUCCESS, but " + result.get() ); } } catch ( final ExecutionException e ) { _log.warn( "An exception occurred when trying to update session " + session.getIdInternal(), e ); } }
/** * Test for issue #105: Make memcached node optional for single-node setup * http://code.google.com/p/memcached-session-manager/issues/detail?id=105 */ @Test public void testBackupSessionFailureWithoutMemcachedNodeIdConfigured105() throws Exception { _service.setMemcachedNodes( "127.0.0.1:11211" ); _service.setSessionBackupAsync(false); _service.startInternal(new MemcachedStorageClient(_memcachedMock)); final MemcachedBackupSession session = createSession( _service ); session.access(); session.endAccess(); session.setAttribute( "foo", "bar" ); @SuppressWarnings( "unchecked" ) final OperationFuture<Boolean> futureMock = mock( OperationFuture.class ); when( futureMock.get( ) ).thenThrow(new ExecutionException(new RuntimeException("Simulated exception."))); when( futureMock.get( anyInt(), any( TimeUnit.class ) ) ).thenThrow(new ExecutionException(new RuntimeException("Simulated exception."))); when( _memcachedMock.set( eq( session.getId() ), anyInt(), any(), any( Transcoder.class ) ) ).thenReturn( futureMock ); final BackupResult backupResult = _service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.FAILURE); verify( _memcachedMock, times( 1 ) ).set( eq( session.getId() ), anyInt(), any(), any( Transcoder.class ) ); }
@Override public Void call() { try { if ( result.get().getStatus() == BackupResultStatus.SKIPPED ) { _readOnlyRequestCache.readOnlyRequest( requestId ); } else { _readOnlyRequestCache.modifyingRequest( requestId ); } } catch ( final Exception e ) { _readOnlyRequestCache.modifyingRequest( requestId ); } return null; }
@Override public Void call() throws Exception { final BackupResult backupResult = _result.get(); if ( _pingSessionIfBackupWasSkipped ) { if ( backupResult.getStatus() == BackupResultStatus.SKIPPED ) { pingSession( _session, _backupSessionService ); } } /* * For non-sticky sessions we store a backup of the session in a secondary memcached node (under a special key * that's resolved by the SuffixBasedNodeLocator), but only when we have more than 1 memcached node configured... */ if ( _storeSecondaryBackup ) { try { if ( _log.isDebugEnabled() ) { _log.debug( "Storing backup in secondary memcached for non-sticky session " + _session.getId() ); } if ( backupResult.getStatus() == BackupResultStatus.SKIPPED ) { pingSessionBackup( _session ); } else { saveSessionBackupFromResult( backupResult ); } saveValidityBackup(); } catch( final RuntimeException e ) { _log.info( "Could not store secondary backup of session " + _session.getIdInternal(), e ); } } return null; }
@Override public Void call() { try { if ( result.get().getStatus() == BackupResultStatus.SKIPPED ) { _readOnlyRequestCache.readOnlyRequest( requestId ); } else { _readOnlyRequestCache.modifyingRequest( requestId ); } } catch ( final Exception e ) { _readOnlyRequestCache.modifyingRequest( requestId ); } return null; }
public void saveSessionBackupFromResult( final BackupResult backupResult ) { final byte[] data = backupResult.getData(); if ( data != null ) { final String key = _sessionIdFormat.createBackupKey( _session.getId() ); _storage.set( key, toMemcachedExpiration(_session.getMemcachedExpirationTimeToSet()), data ); } else { _log.warn( "No data set for backupResultStatus " + backupResult.getStatus() + " for sessionId " + _session.getIdInternal() + ", skipping backup" + " of non-sticky session in secondary memcached." ); } }
private void updateSession( @Nonnull final MemcachedBackupSession session, @Nonnull final BackupSessionService backupSessionService ) throws InterruptedException { final Future<BackupResult> result = backupSessionService.backupSession( session, true ); try { if ( result.get().getStatus() != BackupResultStatus.SUCCESS ) { _log.warn( "Update for session (after unsuccessful ping) did not return SUCCESS, but " + result.get() ); } } catch ( final ExecutionException e ) { _log.warn( "An exception occurred when trying to update session " + session.getIdInternal(), e ); } }
assertEquals(result.get().getStatus(), BackupResultStatus.SKIPPED);
@Override public Void call() throws Exception { final BackupResult backupResult = _result.get(); if ( _pingSessionIfBackupWasSkipped ) { if ( backupResult.getStatus() == BackupResultStatus.SKIPPED ) { pingSession( _session, _backupSessionService ); } } /* * For non-sticky sessions we store a backup of the session in a secondary memcached node (under a special key * that's resolved by the SuffixBasedNodeLocator), but only when we have more than 1 memcached node configured... */ if ( _storeSecondaryBackup ) { try { if ( _log.isDebugEnabled() ) { _log.debug( "Storing backup in secondary memcached for non-sticky session " + _session.getId() ); } if ( backupResult.getStatus() == BackupResultStatus.SKIPPED ) { pingSessionBackup( _session ); } else { saveSessionBackupFromResult( backupResult ); } saveValidityBackup(); } catch( final RuntimeException e ) { _log.info( "Could not store secondary backup of session " + _session.getIdInternal(), e ); } } return null; }
@Override public BackupResult call() throws Exception { final MemcachedBackupSession session3 = _service.findSession(session.getId()); assertSame(session3, session2); assertEquals(session3.getRefCount(), 2); // let the other thread proceed (or wait) barrier.await(); // and wait again so that the other thread can do some work barrier.await(); final Future<BackupResult> result = _service.backupSession(session.getId(), false, "unused"); _service.getTrackingHostValve().resetRequestThreadLocal(); assertEquals(result.get().getStatus(), BackupResultStatus.SUCCESS); // The session should be released now and no longer stored assertFalse(_service.getManager().getSessionsInternal().containsKey(session.getId())); // just some double checking on expectations... assertEquals(session2.getRefCount(), 0); return result.get(); }
@Test(enabled = false) // spurious failures public void testBackupSessionInCouchbaseCluster() throws Exception { final MemcachedSessionService service = _tomcat1.getService(); cluster.add(setupCouchbase(getMaxCouchbasePort() + 1)); service.setMemcachedNodes(getMemcachedNodesConfig(getURIs())); setupCouchbaseClient(); waitForReconnect(service.getStorageClient(), cluster.size(), 1000); waitForReconnect(mc, cluster.size(), 1000); final MemcachedBackupSession session = createSession( service ); final String sessionId = "12345"; session.setId(sessionId); session.setAttribute( "foo", "bar" ); final BackupResult backupResult = service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.SUCCESS); final MemcachedBackupSession loadedSession = transcoderService.deserialize(mc.get(sessionId, ByteArrayTranscoder.INSTANCE), _tomcat1.getManager()); checkSession(loadedSession, session); }
@Test public void testBackupSessionInRedis() throws InterruptedException, ExecutionException, UnsupportedEncodingException, ClassNotFoundException, IOException { final MemcachedSessionService service = _tomcat1.getService(); final MemcachedBackupSession session = createSession( service ); final String sessionId = "12345"; session.setId(sessionId); session.setAttribute( "foo", "bar" ); final BackupResult backupResult = service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.SUCCESS); final MemcachedBackupSession loadedSession = transcoderService.deserialize( redisClient.get(sessionId.getBytes("UTF-8")), _tomcat1.getManager()); checkSession(loadedSession, session); }
public void saveSessionBackupFromResult( final BackupResult backupResult ) { final byte[] data = backupResult.getData(); if ( data != null ) { final String key = _sessionIdFormat.createBackupKey( _session.getId() ); _storage.set( key, toMemcachedExpiration(_session.getMemcachedExpirationTimeToSet()), data ); } else { _log.warn( "No data set for backupResultStatus " + backupResult.getStatus() + " for sessionId " + _session.getIdInternal() + ", skipping backup" + " of non-sticky session in secondary memcached." ); } }
@Test public void testBackupSessionInCouchbase() throws InterruptedException, ExecutionException { final MemcachedSessionService service = _tomcat1.getService(); final MemcachedBackupSession session = createSession( service ); final String sessionId = "12345"; session.setId(sessionId); session.setAttribute( "foo", "bar" ); final BackupResult backupResult = service.backupSession( session.getIdInternal(), false, null ).get(); assertEquals(backupResult.getStatus(), BackupResultStatus.SUCCESS); final MemcachedBackupSession loadedSession = transcoderService.deserialize(mc.get(sessionId, ByteArrayTranscoder.INSTANCE), _tomcat1.getManager()); checkSession(loadedSession, session); }