Bug fixes and added redis sentinel supportability changes.

pull/27/head
Ranjith Manickam 2018-12-04 02:43:03 +05:30
parent c41cfedd77
commit 8aa5359453
2 changed files with 91 additions and 24 deletions

View File

@ -17,9 +17,9 @@ public class DataCacheFactory {
private static final Log LOGGER = LogFactory.getLog(DataCacheFactory.class);
private final long sessionExpiryTime;
private final int sessionExpiryTime;
public DataCacheFactory(long sessionExpiryTime) {
public DataCacheFactory(int sessionExpiryTime) {
this.sessionExpiryTime = sessionExpiryTime;
}

View File

@ -2,6 +2,7 @@ package tomcat.request.session.data.cache.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import tomcat.request.session.data.cache.DataCache;
import tomcat.request.session.data.cache.impl.redis.RedisCache;
import java.io.Serializable;
@ -14,30 +15,42 @@ import java.util.concurrent.ConcurrentHashMap;
public class StandardDataCache extends RedisCache {
private Date lastSessionJobRun;
private boolean triggerRedisSync;
private final int sessionExpiryTime;
private final Map<String, SessionData> sessionData;
private final long sessionExpiryTime;
public StandardDataCache(Properties properties, long sessionExpiryTime) {
public StandardDataCache(Properties properties, int sessionExpiryTime) {
super(properties);
this.sessionExpiryTime = (sessionExpiryTime + 60) / 60;
this.lastSessionJobRun = new Date();
this.sessionExpiryTime = sessionExpiryTime;
this.sessionData = new ConcurrentHashMap<>();
this.lastSessionJobRun = new Date();
this.triggerRedisSync = false;
}
/** {@inheritDoc} */
@Override
public byte[] set(String key, byte[] value) {
triggerSessionExpiry();
this.sessionData.put(key, new SessionData(value));
return super.set(key, value);
try {
return super.set(key, value);
} catch (RuntimeException ex) {
this.triggerRedisSync = true;
}
return value;
}
/** {@inheritDoc} */
@Override
public Long setnx(String key, byte[] value) {
triggerSessionExpiry();
Long retValue = super.setnx(key, value);
Long retValue;
try {
retValue = super.setnx(key, value);
} catch (RuntimeException ex) {
retValue = this.sessionData.containsKey(key) ? 0L : 1L;
this.triggerRedisSync = true;
}
if (retValue == 1L) {
this.sessionData.put(key, new SessionData(value));
}
@ -47,24 +60,39 @@ public class StandardDataCache extends RedisCache {
/** {@inheritDoc} */
@Override
public Long expire(String key, int seconds) {
return super.expire(key, seconds);
try {
return super.expire(key, seconds);
} catch (RuntimeException ex) {
this.triggerRedisSync = true;
}
return null;
}
/** {@inheritDoc} */
@Override
public byte[] get(String key) {
triggerSessionExpiry();
handleSessionData();
if (this.sessionData.containsKey(key)) {
return this.sessionData.get(key).getValue();
}
return super.get(key);
try {
return super.get(key);
} catch (RuntimeException ex) {
this.triggerRedisSync = true;
throw ex;
}
}
/** {@inheritDoc} */
@Override
public Long delete(String key) {
this.sessionData.remove(key);
return super.delete(key);
Object value = this.sessionData.remove(key);
try {
return super.delete(key);
} catch (RuntimeException ex) {
this.triggerRedisSync = true;
}
return (value == null) ? 0L : 1L;
}
/** Session data. */
@ -91,15 +119,54 @@ public class StandardDataCache extends RedisCache {
}
}
/** To trigger session expiry thread. */
private void triggerSessionExpiry() {
/** To handle session data. */
private synchronized void handleSessionData() {
// redis sync
if (this.triggerRedisSync) {
new SessionDataSyncThread(this, this.sessionData, this.sessionExpiryTime);
this.triggerRedisSync = false;
}
// session expiry
long diff = new Date().getTime() - this.lastSessionJobRun.getTime();
long diffMinutes = diff / (60 * 1000) % 60;
if (diffMinutes > 0L) {
synchronized (this) {
new SessionDataExpiryThread(this.sessionData, this.sessionExpiryTime);
this.lastSessionJobRun = new Date();
new SessionDataExpiryThread(this.sessionData, this.sessionExpiryTime);
this.lastSessionJobRun = new Date();
}
}
/** Session data redis sync thread. */
private class SessionDataSyncThread implements Runnable {
private final Log LOGGER = LogFactory.getLog(SessionDataSyncThread.class);
private final DataCache dataCache;
private final int sessionExpiryTime;
private final Map<String, SessionData> sessionData;
SessionDataSyncThread(DataCache dataCache, Map<String, SessionData> sessionData, int sessionExpiryTime) {
this.dataCache = dataCache;
this.sessionData = sessionData;
this.sessionExpiryTime = sessionExpiryTime;
new Thread(this).start();
}
/** {@inheritDoc} */
@Override
public void run() {
try {
for (String key : this.sessionData.keySet()) {
SessionData data = this.sessionData.get(key);
if (data == null) {
continue;
}
this.dataCache.set(key, data.getValue());
this.dataCache.expire(key, this.sessionExpiryTime);
}
} catch (Exception ex) {
LOGGER.error("Error processing session data expiry thread", ex);
}
}
}
@ -109,12 +176,12 @@ public class StandardDataCache extends RedisCache {
private final Log LOGGER = LogFactory.getLog(SessionDataExpiryThread.class);
private final long sessionExpiryTime;
private final int sessionExpiryTime;
private final Map<String, SessionData> sessionData;
SessionDataExpiryThread(Map<String, SessionData> sessionData, long sessionExpiryTime) {
SessionDataExpiryThread(Map<String, SessionData> sessionData, int sessionExpiryTime) {
this.sessionData = sessionData;
this.sessionExpiryTime = sessionExpiryTime;
this.sessionExpiryTime = (sessionExpiryTime + 60) / 60;
new Thread(this).start();
}