Bug fixes and added redis sentinel supportability changes.
parent
c41cfedd77
commit
8aa5359453
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue