Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Create a lazy wrapper for StoreClient

  • Loading branch information...
commit 3ad24b58d636adf1fb161b155df44847cd8481b0 1 parent 84bdd65
@afeinberg afeinberg authored
View
125 src/java/voldemort/client/LazyStoreClient.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2008-2011 LinkedIn, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package voldemort.client;
+
+import voldemort.VoldemortException;
+import voldemort.cluster.Node;
+import voldemort.versioning.ObsoleteVersionException;
+import voldemort.versioning.Version;
+import voldemort.versioning.Versioned;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * A {@link StoreClient} with lazy initialization. This is useful
+ * existing codes that initializes clients at service deployment time,
+ * when the servers may or may not be available
+ *
+ */
+public class LazyStoreClient<K, V> implements StoreClient<K, V> {
+
+ private final Callable<StoreClient<K, V>> storeClientThunk;
+ private StoreClient<K, V> storeClient;
+
+ public LazyStoreClient(Callable<StoreClient<K, V>> storeClientThunk) {
+ this.storeClientThunk = storeClientThunk;
+ }
+
+ protected synchronized StoreClient<K, V> getStoreClient() {
+ if(storeClient == null)
+ storeClient = initStoreClient();
+
+ return storeClient;
+ }
+
+ protected StoreClient<K, V> initStoreClient() {
+ try {
+ return storeClientThunk.call();
+ } catch(BootstrapFailureException bfe) {
+ throw bfe;
+ } catch(Exception e) {
+ throw new VoldemortException("Unexpected exception during initialization",
+ e);
+ }
+ }
+
+ public V getValue(K key) {
+ return getStoreClient().getValue(key);
+ }
+
+ public V getValue(K key, V defaultValue) {
+ return getStoreClient().getValue(key, defaultValue);
+ }
+
+ public Versioned<V> get(K key) {
+ return getStoreClient().get(key);
+ }
+
+ public Versioned<V> get(K key, Object transforms) {
+ return getStoreClient().get(key, transforms);
+ }
+
+ public Map<K, Versioned<V>> getAll(Iterable<K> keys) {
+ return getStoreClient().getAll(keys);
+ }
+
+ public Map<K, Versioned<V>> getAll(Iterable<K> keys, Map<K, Object> transforms) {
+ return getStoreClient().getAll(keys, transforms);
+ }
+
+ public Versioned<V> get(K key, Versioned<V> defaultValue) {
+ return getStoreClient().get(key, defaultValue);
+ }
+
+ public void put(K key, V value) {
+ getStoreClient().put(key, value);
+ }
+
+ public void put(K key, V value, Object transforms) {
+ getStoreClient().put(key, value, transforms);
+ }
+
+ public void put(K key, Versioned<V> vVersioned) throws ObsoleteVersionException {
+ getStoreClient().put(key, vVersioned);
+ }
+
+ public boolean putIfNotObsolete(K key, Versioned<V> versioned) {
+ return getStoreClient().putIfNotObsolete(key, versioned);
+ }
+
+ public boolean applyUpdate(UpdateAction<K, V> action) {
+ return getStoreClient().applyUpdate(action);
+ }
+
+ public boolean applyUpdate(UpdateAction<K, V> action, int maxTries) {
+ return getStoreClient().applyUpdate(action, maxTries);
+ }
+
+ public boolean delete(K key) {
+ return getStoreClient().delete(key);
+ }
+
+ public boolean delete(K key, Version version) {
+ return getStoreClient().delete(key, version);
+ }
+
+ public List<Node> getResponsibleNodes(K key) {
+ return getStoreClient().getResponsibleNodes(key);
+ }
+}
View
41 test/unit/voldemort/client/DefaultStoreClientTest.java
@@ -1,9 +1,26 @@
+/*
+ * Copyright 2008-2010 LinkedIn, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
package voldemort.client;
import java.util.Arrays;
import java.util.Map;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
import voldemort.serialization.Serializer;
import voldemort.serialization.StringSerializer;
import voldemort.utils.SystemTime;
@@ -12,13 +29,15 @@
import voldemort.versioning.VectorClock;
import voldemort.versioning.Versioned;
-public class DefaultStoreClientTest extends TestCase {
+import static org.junit.Assert.*;
+
+public class DefaultStoreClientTest {
- private int nodeId;
- private Time time;
- private StoreClient<String, String> client;
+ protected int nodeId;
+ protected Time time;
+ protected StoreClient<String, String> client;
- @Override
+ @Before
public void setUp() {
this.nodeId = 0;
this.time = SystemTime.INSTANCE;
@@ -32,6 +51,7 @@ public void setUp() {
this.client = factory.getStoreClient("test");
}
+ @Test
public void testGet() {
assertEquals("GET of non-existant key should return null.", null, client.get("k"));
client.put("k", "v");
@@ -40,6 +60,7 @@ public void testGet() {
.getVersion());
}
+ @Test
public void testGetWithDefault() {
assertEquals("GET of missing key should return default.",
new Versioned<String>("v"),
@@ -56,12 +77,14 @@ public void testGetWithDefault() {
assertNotNull(client.get("k").getVersion());
}
+ @Test
public void testGetUnversioned() {
assertEquals("GET of non-existant key should be null.", null, client.getValue("k"));
client.put("k", "v");
assertEquals("GET of k should return v, if v is there.", "v", client.getValue("k"));
}
+ @Test
public void testGetUnversionedWithDefault() {
assertEquals("GET of non-existant key should return default.", "v", client.getValue("k",
"v"));
@@ -72,6 +95,7 @@ public void testGetUnversionedWithDefault() {
client.getValue("k", "v2"));
}
+ @Test
public void testPutVersioned() {
client.put("k", Versioned.value("v"));
Versioned<String> v = client.get("k");
@@ -96,6 +120,7 @@ public void testPutVersioned() {
client.get("k").getVersion());
}
+ @Test
public void testPutUnversioned() {
client.put("k", "v");
assertEquals("GET should fetch the value set by PUT", "v", client.getValue("k"));
@@ -103,6 +128,7 @@ public void testPutUnversioned() {
assertEquals("Overwrite of value should succeed.", "v2", client.getValue("k"));
}
+ @Test
public void testPutIfNotObsolete() {
client.putIfNotObsolete("k", new Versioned<String>("v"));
assertEquals("PUT of non-obsolete version should succeed.", "v", client.getValue("k"));
@@ -110,6 +136,7 @@ public void testPutIfNotObsolete() {
assertEquals("Failed PUT should not change the value stored.", "v", client.getValue("k"));
}
+ @Test
public void testDelete() {
assertFalse("Delete of non-existant key should be false.", client.delete("k"));
client.put("k", "v");
@@ -117,6 +144,7 @@ public void testDelete() {
assertNull("After a successful delete(k), get(k) should return null.", client.get("k"));
}
+ @Test
public void testDeleteVersion() {
assertFalse("Delete of non-existant key should be false.", client.delete("k",
new VectorClock()));
@@ -129,6 +157,7 @@ public void testDeleteVersion() {
assertNull("After a successful delete(k), get(k) should return null.", client.get("k"));
}
+ @Test
public void testGetAll() {
client.put("k", "v");
client.put("l", "m");
View
74 test/unit/voldemort/client/LazyStoreClientTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008-2011 LinkedIn, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package voldemort.client;
+
+import org.junit.Before;
+import org.junit.Test;
+import voldemort.serialization.Serializer;
+import voldemort.serialization.StringSerializer;
+import voldemort.utils.SystemTime;
+
+import java.util.concurrent.Callable;
+
+import static org.mockito.Mockito.*;
+
+/**
+ */
+public class LazyStoreClientTest extends DefaultStoreClientTest {
+
+ private MockStoreClientFactory factory;
+
+ @Override
+ @Before
+ public void setUp() {
+ this.nodeId = 0;
+ this.time = SystemTime.INSTANCE;
+ Serializer<String> serializer = new StringSerializer();
+ this.factory = new MockStoreClientFactory(serializer,
+ serializer,
+ null,
+ serializer,
+ nodeId,
+ time);
+ this.client = newLazyStoreClient(factory);
+ }
+
+ @Test
+ public void testInitializationShouldBeLazy() {
+ StoreClientFactory spyFactory = spy(factory);
+ LazyStoreClient<String, String> spyLazyClient = spy(newLazyStoreClient(spyFactory));
+
+ // Check that we don't initialize upon construction
+ verify(spyFactory, times(0)).getStoreClient("test");
+
+ // Check that we initialize once and only once
+ for(int i = 0; i < 10; i++)
+ spyLazyClient.get("test");
+
+ verify(spyFactory, times(1)).getStoreClient("test");
+ verify(spyLazyClient, times(1)).initStoreClient();
+ }
+
+ private LazyStoreClient<String, String> newLazyStoreClient(final StoreClientFactory factory) {
+ return new LazyStoreClient<String, String>(new Callable<StoreClient<String, String>>() {
+
+ public StoreClient<String, String> call() throws Exception {
+ return factory.getStoreClient("test");
+ }
+ });
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.