|
|
|
@ -15,19 +15,23 @@
|
|
|
|
|
*/
|
|
|
|
|
package org.redisson.hibernate.region;
|
|
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Properties;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
|
|
import org.hibernate.cache.CacheException;
|
|
|
|
|
import org.hibernate.cache.spi.CacheDataDescription;
|
|
|
|
|
import org.hibernate.cache.spi.GeneralDataRegion;
|
|
|
|
|
import org.hibernate.cache.spi.RegionFactory;
|
|
|
|
|
import org.hibernate.cache.spi.TransactionalDataRegion;
|
|
|
|
|
import org.hibernate.engine.spi.SessionImplementor;
|
|
|
|
|
import org.redisson.api.RFuture;
|
|
|
|
|
import org.redisson.api.RMapCache;
|
|
|
|
|
import org.redisson.connection.ConnectionManager;
|
|
|
|
|
import org.redisson.hibernate.RedissonRegionFactory;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Properties;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
@ -36,18 +40,24 @@ import org.redisson.hibernate.RedissonRegionFactory;
|
|
|
|
|
*/
|
|
|
|
|
public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
|
|
|
|
|
|
|
|
|
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
|
|
|
|
|
|
|
|
final RMapCache<Object, Object> mapCache;
|
|
|
|
|
final RegionFactory regionFactory;
|
|
|
|
|
final CacheDataDescription metadata;
|
|
|
|
|
final ConnectionManager connectionManager;
|
|
|
|
|
|
|
|
|
|
int ttl;
|
|
|
|
|
int maxIdle;
|
|
|
|
|
|
|
|
|
|
public BaseRegion(RMapCache<Object, Object> mapCache, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) {
|
|
|
|
|
boolean fallback;
|
|
|
|
|
volatile boolean fallbackMode;
|
|
|
|
|
|
|
|
|
|
public BaseRegion(RMapCache<Object, Object> mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) {
|
|
|
|
|
super();
|
|
|
|
|
this.mapCache = mapCache;
|
|
|
|
|
this.regionFactory = regionFactory;
|
|
|
|
|
this.metadata = metadata;
|
|
|
|
|
this.connectionManager = connectionManager;
|
|
|
|
|
|
|
|
|
|
String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX);
|
|
|
|
|
if (maxEntries != null) {
|
|
|
|
@ -61,6 +71,9 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
|
|
|
|
|
if (maxIdleTime != null) {
|
|
|
|
|
maxIdle = Integer.valueOf(maxIdleTime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String fallbackValue = (String) properties.getOrDefault(RedissonRegionFactory.FALLBACK, "false");
|
|
|
|
|
fallback = Boolean.valueOf(fallbackValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String getProperty(Properties properties, String name, String defaultKey, String suffix) {
|
|
|
|
@ -75,6 +88,20 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ping() {
|
|
|
|
|
fallbackMode = true;
|
|
|
|
|
connectionManager.newTimeout(t -> {
|
|
|
|
|
RFuture<Boolean> future = mapCache.isExistsAsync();
|
|
|
|
|
future.onComplete((r, ex) -> {
|
|
|
|
|
if (ex == null) {
|
|
|
|
|
fallbackMode = false;
|
|
|
|
|
} else {
|
|
|
|
|
ping();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}, 1, TimeUnit.SECONDS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isTransactionAware() {
|
|
|
|
|
// TODO Auto-generated method stub
|
|
|
|
@ -102,9 +129,17 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean contains(Object key) {
|
|
|
|
|
if (fallbackMode) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
return mapCache.containsKey(key);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
if (fallback) {
|
|
|
|
|
ping();
|
|
|
|
|
logger.error(e.getMessage(), e);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
throw new CacheException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -142,36 +177,68 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Object get(SessionImplementor session, Object key) throws CacheException {
|
|
|
|
|
if (fallbackMode) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
return mapCache.get(key);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
if (fallback) {
|
|
|
|
|
ping();
|
|
|
|
|
logger.error(e.getMessage(), e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
throw new CacheException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void put(SessionImplementor session, Object key, Object value) throws CacheException {
|
|
|
|
|
if (fallbackMode) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
if (fallback) {
|
|
|
|
|
ping();
|
|
|
|
|
logger.error(e.getMessage(), e);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
throw new CacheException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void evict(Object key) throws CacheException {
|
|
|
|
|
if (fallbackMode) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
mapCache.fastRemove(key);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
if (fallback) {
|
|
|
|
|
ping();
|
|
|
|
|
logger.error(e.getMessage(), e);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
throw new CacheException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void evictAll() throws CacheException {
|
|
|
|
|
if (fallbackMode) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
mapCache.clear();
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
if (fallback) {
|
|
|
|
|
ping();
|
|
|
|
|
logger.error(e.getMessage(), e);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
throw new CacheException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|