class ExpirationListener implements RedisFacade.RedisPubSub {

  @Override
  public void onPMessage(byte[] pattern, byte[] channelBuf, byte[] message) {
    // Only accept messages expiration notification channel
    // and only those that match our key prefix.
    if (channelBuf == null || message == null) {
      return;
    }
    if (!isExpiredChannel(channelBuf)) {
      return;
    }
    if (!isExpireKey(message)) {
      return;
    }

    String body = encode(message);
    if (logger.isDebugEnabled()) {
      logger.debug("Got notification for channel: '{}', body: '{}'", encode(channelBuf), body);
    }

    String sessionId = RedisSessionRepository.extractSessionId(body);
    logger.info("Session expired event for sessionId: '{}'", sessionId);

    // We run session delete in another thread, otherwise we would block
    // listener.
    sessionManager.deleteAsync(sessionId, true);
  }

    ExpirationListener(SessionManager sessionManager, String keyPrefix);

}