@Override public void append(long key, ByteBuffer payLoad) throws TimeoutException { storeProxy.append(key, payLoad); }
@Override public void clear() throws TimeoutException { delegate.clear(); } }
@Override public Chain get(long key) throws TimeoutException { return storeProxy.get(key); }
@Override public void releaseServerStoreProxy(ServerStoreProxy storeProxy, boolean isReconnect) { connectionState.removeClusterTierClientEntity(storeProxy.getCacheId()); if (!isReconnect) { storeProxy.close(); } else { reconnectSet.add(storeProxy.getCacheId()); } }
@Test @SuppressWarnings("unchecked") public void testRemoveDoesNotReplaceChainOnMisses() throws Exception { ResolvedChain<Long, String> resolvedChain = mock(ResolvedChain.class); when(resolvedChain.getResolvedResult(anyLong())).thenReturn(null); //simulate a key miss on chain resolution EternalChainResolver<Long, String> resolver = mock(EternalChainResolver.class); when(resolver.resolve(any(Chain.class), anyLong(), anyLong())).thenReturn(resolvedChain); OperationsCodec<Long, String> codec = mock(OperationsCodec.class); when(codec.encode(any())).thenReturn(ByteBuffer.allocate(0)); ServerStoreProxy proxy = mock(ServerStoreProxy.class); when(proxy.getAndAppend(anyLong(), any(ByteBuffer.class))).thenReturn(mock(Chain.class)); TimeSource timeSource = mock(TimeSource.class); ClusteredStore<Long, String> store = new ClusteredStore<>(config, codec, resolver, proxy, timeSource); store.remove(1L); verify(proxy, never()).replaceAtHead(anyLong(), any(Chain.class), any(Chain.class)); }
@Override public Chain getAndAppend(long key, ByteBuffer payLoad) throws TimeoutException { return storeProxy.getAndAppend(key, payLoad); }
@Test public void untrackedMessageAreNotStored() throws Exception { // Nothing tracked assertThat(activeMessageHandler.getTrackedClients().count()).isZero(); List<Element> elements = new ArrayList<>(1); elements.add(getElement(createPayload(44L))); // Send a replace message, those are not tracked storeProxy.replaceAtHead(44L, getChain(elements), getChain(new ArrayList<>(0))); // Not tracked as well storeProxy.get(42L); assertThat(activeMessageHandler.getTrackedClients().count()).isZero(); }
@Override public String getCacheId() { return storeProxy.getCacheId(); }
@Override public void replaceAtHead(long key, Chain expect, Chain update) { delegate.replaceAtHead(key, expect, update); }
@Override public void close() { storeProxy.close(); }
@Test @SuppressWarnings("unchecked") public void testConditionalRemoveDoesNotReplaceChainOnKeyMiss() throws Exception { ResolvedChain<Long, String> resolvedChain = mock(ResolvedChain.class); when(resolvedChain.getResolvedResult(anyLong())).thenReturn(null); //simulate a key miss on chain resolution EternalChainResolver<Long, String> resolver = mock(EternalChainResolver.class); when(resolver.resolve(any(Chain.class), anyLong(), anyLong())).thenReturn(resolvedChain); OperationsCodec<Long, String> codec = mock(OperationsCodec.class); when(codec.encode(any())).thenReturn(ByteBuffer.allocate(0)); ServerStoreProxy proxy = mock(ServerStoreProxy.class); when(proxy.getAndAppend(anyLong(), any(ByteBuffer.class))).thenReturn(mock(Chain.class)); TimeSource timeSource = mock(TimeSource.class); ClusteredStore<Long, String> store = new ClusteredStore<>(config, codec, resolver, proxy, timeSource); store.remove(1L, "foo"); verify(proxy, never()).replaceAtHead(anyLong(), any(Chain.class), any(Chain.class)); }
@Override public Chain getAndAppend(final long key, final ByteBuffer payLoad) throws TimeoutException { return delegate.getAndAppend(key, payLoad); }
@Test public void testGetThatDoesNotCompactsInvokesReplace() throws Exception { TestTimeSource timeSource = new TestTimeSource(); timeSource.advanceTime(134556L); long now = timeSource.getTimeMillis(); OperationsCodec<Long, String> operationsCodec = new OperationsCodec<>(new LongSerializer(), new StringSerializer()); @SuppressWarnings("unchecked") EternalChainResolver<Long, String> chainResolver = mock(EternalChainResolver.class); @SuppressWarnings("unchecked") ResolvedChain<Long, String> resolvedChain = mock(ResolvedChain.class); when(resolvedChain.isCompacted()).thenReturn(false); when(chainResolver.resolve(any(Chain.class), eq(42L), eq(now))).thenReturn(resolvedChain); ServerStoreProxy serverStoreProxy = mock(ServerStoreProxy.class); Chain chain = mock(Chain.class); when(chain.isEmpty()).thenReturn(false); long longKey = HashUtils.intHashToLong(new Long(42L).hashCode()); when(serverStoreProxy.get(longKey)).thenReturn(chain); ClusteredStore<Long, String> clusteredStore = new ClusteredStore<>(config, operationsCodec, chainResolver, serverStoreProxy, timeSource); clusteredStore.get(42L); verify(serverStoreProxy, never()).replaceAtHead(eq(longKey), eq(chain), any(Chain.class)); }
@Override public String getCacheId() { return delegate.getCacheId(); }
@Override public void releaseServerStoreProxy(ServerStoreProxy storeProxy, boolean isReconnect) { connectionState.removeClusterTierClientEntity(storeProxy.getCacheId()); if (!isReconnect) { storeProxy.close(); } else { reconnectSet.add(storeProxy.getCacheId()); } }
@Override public void replaceAtHead(long key, Chain expect, Chain update) { storeProxy.replaceAtHead(key, expect, update); }
@Override public void close() { delegate.close(); }
protected V silentRemove(K key, V value) throws StoreAccessException { try { ConditionalRemoveOperation<K, V> operation = new ConditionalRemoveOperation<>(key, value, timeSource.getTimeMillis()); ByteBuffer payload = codec.encode(operation); long extractedKey = extractLongKey(key); Chain chain = storeProxy.getAndAppend(extractedKey, payload); ResolvedChain<K, V> resolvedChain = resolver.resolve(chain, key, timeSource.getTimeMillis()); Result<K, V> result = resolvedChain.getResolvedResult(key); if (result != null && value.equals(result.getValue())) { storeProxy.replaceAtHead(extractedKey, chain, resolvedChain.getCompactedChain()); } return result == null ? null : result.getValue(); } catch (Exception re) { throw handleException(re); } }
@Test public void testGetAndAppend() throws Exception { doThrow(storeProxyException).when(proxy).getAndAppend(anyLong(), any(ByteBuffer.class)); exception.expect(ReconnectInProgressException.class); serverStoreProxy.getAndAppend(0, ByteBuffer.allocate(2)); }
@Override public void append(final long key, final ByteBuffer payLoad) throws TimeoutException { delegate.append(key, payLoad); }