From 3110684e12927cafb1a90a2842223fd674032ab8 Mon Sep 17 00:00:00 2001 From: Rob Austin Date: Fri, 17 Oct 2014 16:39:25 +0100 Subject: [PATCH] HCOLL-167 improved passing errors back --- .../chronicle/map/StatelessMapClient.java | 82 +++++++++++++------ .../map/StatelessServerConnector.java | 28 ++++++- .../chronicle/map/StatelessClientTest.java | 4 +- 3 files changed, 82 insertions(+), 32 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/map/StatelessMapClient.java b/src/main/java/net/openhft/chronicle/map/StatelessMapClient.java index f74ac48a7..993441d5c 100644 --- a/src/main/java/net/openhft/chronicle/map/StatelessMapClient.java +++ b/src/main/java/net/openhft/chronicle/map/StatelessMapClient.java @@ -23,7 +23,7 @@ import static net.openhft.chronicle.map.StatelessMapClient.EventId.*; * * @author Rob Austin. */ -class StatelessMapClient { +class StatelessMapClient implements ChronicleMap { private static final Logger LOG = LoggerFactory.getLogger(StatelessMapClient.class); @@ -95,7 +95,7 @@ class StatelessMapClient { return null; } - public void close() throws IOException { + public void close() { throw new UnsupportedOperationException("This is not supported in the " + this.getClass() .getSimpleName()); } @@ -118,7 +118,7 @@ class StatelessMapClient { private final KeyValueSerializer keyValueSerializer; - public synchronized V putIfAbsent(K key, V value) throws IOException { + public synchronized V putIfAbsent(K key, V value) { long sizeLocation = writeEvent(PUT_IF_ABSENT); writeKey(key); @@ -127,7 +127,7 @@ class StatelessMapClient { } - public synchronized boolean remove(Object key, Object value) throws IOException { + public synchronized boolean remove(Object key, Object value) { long sizeLocation = writeEvent(REMOVE_WITH_VALUE); writeKey((K) key); writeValue((V) value); @@ -138,7 +138,7 @@ class StatelessMapClient { } - public synchronized boolean replace(K key, V oldValue, V newValue) throws IOException { + public synchronized boolean replace(K key, V oldValue, V newValue) { long sizeLocation = writeEvent(REPLACE_WITH_OLD_AND_NEW_VALUE); writeKey(key); writeValue(oldValue); @@ -149,7 +149,7 @@ class StatelessMapClient { } - public synchronized V replace(K key, V value) throws IOException { + public synchronized V replace(K key, V value) { long sizeLocation = writeEvent(REPLACE); writeKey(key); writeValue(value); @@ -159,7 +159,7 @@ class StatelessMapClient { } - public synchronized int size() throws IOException { + public synchronized int size() { long sizeLocation = writeEvent(SIZE); @@ -168,7 +168,7 @@ class StatelessMapClient { } - public synchronized boolean isEmpty() throws IOException { + public synchronized boolean isEmpty() { long sizeLocation = writeEvent(IS_EMPTY); // get the data back from the server @@ -176,7 +176,7 @@ class StatelessMapClient { } - public synchronized boolean containsKey(Object key) throws IOException { + public synchronized boolean containsKey(Object key) { long sizeLocation = writeEvent(CONTAINS_KEY); writeKey((K) key); @@ -186,7 +186,7 @@ class StatelessMapClient { } - public synchronized boolean containsValue(Object value) throws IOException { + public synchronized boolean containsValue(Object value) { long sizeLocation = writeEvent(CONTAINS_VALUE); writeValue((V) value); @@ -195,14 +195,14 @@ class StatelessMapClient { } - public synchronized long longSize() throws IOException { + public synchronized long longSize() { long sizeLocation = writeEvent(LONG_SIZE); // get the data back from the server return blockingFetch(sizeLocation).readLong(); } - public synchronized V get(Object key) throws IOException { + public synchronized V get(Object key) { long sizeLocation = writeEvent(GET); writeKey((K) key); @@ -222,19 +222,21 @@ class StatelessMapClient { } - public synchronized V put(K key, V value) throws IOException { + public synchronized V put(K key, V value) { long sizeLocation = writeEvent(PUT); writeKey(key); writeValue(value); // get the data back from the server + return readKey(sizeLocation); + } - public synchronized V remove(Object key) throws IOException { + public synchronized V remove(Object key) { long sizeLocation = writeEvent(REMOVE); writeKey((K) key); @@ -244,7 +246,7 @@ class StatelessMapClient { } - public synchronized void putAll(Map map) throws IOException { + public synchronized void putAll(Map map) { for (Map.Entry e : map.entrySet()) { put(e.getKey(), e.getValue()); @@ -267,17 +269,19 @@ class StatelessMapClient { } - public synchronized void clear() throws IOException { + public synchronized void clear() { long sizeLocation = writeEvent(CLEAR); // get the data back from the server + blockingFetch(sizeLocation); + } @NotNull - public synchronized Set keySet() throws IOException { + public synchronized Set keySet() { long sizeLocation = writeEvent(KEY_SET); // get the data back from the server @@ -287,7 +291,7 @@ class StatelessMapClient { @NotNull - public synchronized Collection values() throws IOException { + public synchronized Collection values() { long sizeLocation = writeEvent(VALUES); // get the data back from the server @@ -309,7 +313,7 @@ class StatelessMapClient { @NotNull - public synchronized Set> entrySet() throws IOException { + public synchronized Set> entrySet() { long sizeLocation = writeEvent(ENTRY_SET); // get the data back from the server @@ -417,11 +421,9 @@ class StatelessMapClient { public final V setValue(V newValue) { V oldValue = value; - try { - StatelessMapClient.this.put((K) getKey(), (V) newValue); - } catch (IOException e) { - LOG.error("", e); - } + + StatelessMapClient.this.put((K) getKey(), (V) newValue); + return oldValue; } @@ -450,7 +452,17 @@ class StatelessMapClient { } } - private Bytes blockingFetch(long sizeLocation) throws IOException { + private Bytes blockingFetch(long sizeLocation) { + try { + return blockingFetchThrowable(sizeLocation); + } catch (IOException e) { + throw new RuntimeIOException(e); + } + + } + + + private Bytes blockingFetchThrowable(long sizeLocation) throws IOException { long transactionId = nextUniqueTransaction(); LOG.info("sending data with transactionId=" + transactionId); @@ -487,6 +499,17 @@ class StatelessMapClient { ", does not match the expected transaction-id=" + transactionId); } + if (isException) { + int len = in.readUnsignedShort(); + + in.limit(in.position() + len); + + Object o = in.readObject(); + RuntimeException runtimeException = (RuntimeException) o; + throw runtimeException; + } + + return in; } @@ -505,7 +528,7 @@ class StatelessMapClient { keyValueSerializer.writeKey(key, out); } - private V readKey(final long sizeLocation) throws IOException { + private V readKey(final long sizeLocation) { return keyValueSerializer.readValue(blockingFetch(sizeLocation)); } @@ -533,3 +556,10 @@ interface Buffer { ByteBufferBytes get(); } + +class RuntimeIOException extends RuntimeException { + + public RuntimeIOException(IOException e) { + super(e); + } +} diff --git a/src/main/java/net/openhft/chronicle/map/StatelessServerConnector.java b/src/main/java/net/openhft/chronicle/map/StatelessServerConnector.java index 497c85a64..71289cd32 100644 --- a/src/main/java/net/openhft/chronicle/map/StatelessServerConnector.java +++ b/src/main/java/net/openhft/chronicle/map/StatelessServerConnector.java @@ -101,8 +101,13 @@ class StatelessServerConnector { V newValue = readValue(in); long sizeLocation = reflectTransactionId(in, out); - map.replace(key, oldValue, newValue); - + try { + map.replace(key, oldValue, newValue); + } catch (RuntimeException e) { + writeException(e, out); + writeSizeAndFlags(sizeLocation, true, out); + return; + } writeSizeAndFlags(sizeLocation, false, out); } @@ -142,8 +147,25 @@ class StatelessServerConnector { public void get(Bytes in, Bytes out) { K k = readKey(in); long sizeLocation = reflectTransactionId(in, out); - writeValue(map.get(k), out); + try { + writeValue(map.get(k), out); + } catch (RuntimeException e) { + writeException(e, out); + writeSizeAndFlags(sizeLocation, true, out); + return; + } writeSizeAndFlags(sizeLocation, false, out); + + } + + private void writeException(RuntimeException e, Bytes out) { + + long start = out.position(); + out.skip(2); + out.writeObject(e); + long len = out.position() - (start + 2L); + out.writeUnsignedShort(start,(int) len); + } public void put(Bytes in, Bytes out) { diff --git a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java index 87b2b6c7a..9601e9032 100644 --- a/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java +++ b/src/test/java/net/openhft/chronicle/map/StatelessClientTest.java @@ -41,9 +41,7 @@ public class StatelessClientTest { Assert.assertEquals("EXAMPLE-10", map.get(10)); - // Assert.assertEquals("EXAMPLE-10", map.get(10)); - - // Assert.assertEquals(1, map.size()); + Assert.assertEquals(1, map.size()); } }