Skip to content

Commit

Permalink
INTERNAL: get NullValue instance from arcus server
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviarla committed May 21, 2024
1 parent 4d96278 commit d1b19ad
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 42 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<version>1.13.5</version>

<properties>
<org.springframework.version>4.3.0.RELEASE</org.springframework.version>
<org.springframework.version>4.3.10.RELEASE</org.springframework.version>
<org.slf4j.version>1.7.24</org.slf4j.version>
<org.apache.logging.log4j.version>2.17.1</org.apache.logging.log4j.version>
<arcus.client.version>1.13.4</arcus.client.version>
Expand Down
81 changes: 40 additions & 41 deletions src/main/java/com/navercorp/arcus/spring/cache/ArcusCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractValueAdaptingCache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;
Expand Down Expand Up @@ -76,10 +76,12 @@
* </p>
*/
@SuppressWarnings("DeprecatedIsStillUsed")
public class ArcusCache implements Cache, InitializingBean {
public class ArcusCache extends AbstractValueAdaptingCache implements InitializingBean {

public static final long DEFAULT_TIMEOUT_MILLISECONDS = 700L;

public static final boolean DEFAULT_ALLOW_NULL_VALUES = true;

private final Logger logger = LoggerFactory.getLogger(this.getClass());

private String name;
Expand All @@ -97,10 +99,11 @@ public class ArcusCache implements Cache, InitializingBean {
private ArcusFrontCache arcusFrontCache;

public ArcusCache() {

super(DEFAULT_ALLOW_NULL_VALUES);
}

ArcusCache(String name, ArcusClientPool clientPool, ArcusCacheConfiguration configuration) {
super(configuration.isAllowNullValues());
this.name = name;
this.arcusClient = clientPool;
this.serviceId = configuration.getServiceId();
Expand Down Expand Up @@ -128,70 +131,66 @@ public Object getNativeCache() {

@Nullable
@Override
public ValueWrapper get(Object key) {
Object value = null;
protected Object lookup(Object key) {
try {
value = getValue(createArcusKey(key));
return getValue(createArcusKey(key));
} catch (Exception e) {
logger.info(e.getMessage());
if (wantToGetException) {
throw toRuntimeException(e);
}
throw toRuntimeException(e);
}
return (value != null ? new SimpleValueWrapper(value) : null);
}

@SuppressWarnings("unchecked")
@Nullable
@Override
public <T> T get(Object key, Class<T> type) {
public ValueWrapper get(Object key) {
try {
Object value = getValue(createArcusKey(key));
if (value != null && type != null && !type.isInstance(value)) {
throw new IllegalStateException(
"Cached value is not of required type [" + type.getName() + "]: " + value);
}
return (T) value;
} catch (Exception e) {
return super.get(key);
} catch (RuntimeException e) {
logger.info(e.getMessage());
throw toRuntimeException(e);
if (wantToGetException) {
throw e;
}
return null;
}
}

@SuppressWarnings("unchecked")
@Nullable
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
ValueWrapper result = super.get(key);

return result != null ? (T) result.get() : getSynchronized(key, valueLoader);
}

@Nullable
@SuppressWarnings("unchecked")
private <T> T getSynchronized(Object key, Callable<T> valueLoader) {
String arcusKey = createArcusKey(key);
Object value;
try {
value = getValue(arcusKey);
if (value != null) {
return (T) value;
}
acquireWriteLockOnKey(arcusKey);
ValueWrapper result = super.get(key);
return result != null ? (T) result.get() : loadValue(arcusKey, valueLoader);
} finally {
releaseWriteLockOnKey(arcusKey);
}
}

private <T> T loadValue(String key, Callable<T> valueLoader) {
T value;
try {
value = valueLoader.call();
} catch (Exception e) {
logger.info(e.getMessage());
throw toRuntimeException(e);
throw new ValueRetrievalException(key, valueLoader, e);
}

try {
acquireWriteLockOnKey(arcusKey);
value = getValue(arcusKey);
if (value == null) {
try {
value = valueLoader.call();
} catch (Exception e) {
throw new ValueRetrievalException(key, valueLoader, e);
}
putValue(arcusKey, value);
}
return (T) value;
putValue(key, value);
} catch (Exception e) {
logger.info(e.getMessage());
throw toRuntimeException(e);
} finally {
releaseWriteLockOnKey(arcusKey);
}

return value;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class ArcusCacheConfiguration implements InitializingBean {
private Transcoder<Object> operationTranscoder;
private ArcusFrontCache arcusFrontCache;
private boolean forceFrontCaching;
private boolean allowNullValues = ArcusCache.DEFAULT_ALLOW_NULL_VALUES;

public String getServiceId() {
return serviceId;
Expand Down Expand Up @@ -104,6 +105,14 @@ public void setForceFrontCaching(boolean forceFrontCaching) {
this.forceFrontCaching = forceFrontCaching;
}

public boolean isAllowNullValues() {
return this.allowNullValues;
}

public void setAllowNullValues(boolean allowNullValues) {
this.allowNullValues = allowNullValues;
}

@Override
public void afterPropertiesSet() {
Assert.isTrue(timeoutMilliSeconds > 0, "TimeoutMilliSeconds must be larger than 0.");
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/com/navercorp/arcus/spring/cache/ArcusCacheTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.junit.Test;

import org.springframework.cache.Cache;
import org.springframework.cache.support.NullValue;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -225,6 +226,22 @@ public void testGet_FrontCache_Null() {
assertNull(value);
}

@Test
public void testGet_NullValue() {
// given
when(arcusClientPool.asyncGet(arcusKey))
.thenReturn(createGetFuture(NullValue.INSTANCE));

// when
Cache.ValueWrapper value = arcusCache.get(ARCUS_STRING_KEY);

// then
verify(arcusClientPool, times(1))
.asyncGet(arcusKey);
assertNotNull(value);
assertNull(value.get());
}

@Test
public void testPut() {
// given
Expand Down

0 comments on commit d1b19ad

Please sign in to comment.