HCOLL-184 stateless client now returns the server and client versions

This commit is contained in:
Rob Austin
2014-12-23 12:07:51 +00:00
parent 9b7279daf0
commit e257fca466
7 changed files with 93 additions and 46 deletions
@@ -30,20 +30,28 @@ import java.io.Reader;
*/
class BuildVersion {
static String version = null;
/**
* @return version of ChronicleMap being used, or NULL if its not known
*/
public static String readVersion() {
public synchronized static String readVersion() {
if (version != null) {
return version;
}
// the best way to get the version is to read it from the manifest
final String version = getVersionFromManifest();
final String versionFromManifest = getVersionFromManifest();
if (version != null)
if (versionFromManifest != null) {
version = versionFromManifest;
return version;
}
// as a fall back for development, we will read the version from the pom file
return getVersionFromPom();
version = getVersionFromPom();
return version;
}
/**
@@ -52,7 +52,6 @@ import static net.openhft.chronicle.map.StatelessChronicleMap.EventId.*;
*/
class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Cloneable {
private static final String START_OF = "Attempt to write ";
private static final Logger LOG = LoggerFactory.getLogger(StatelessChronicleMap.class);
private static final byte STATELESS_CLIENT_IDENTIFIER = (byte) -127;
@@ -114,7 +113,8 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
PUT_IF_ABSENT,
REMOVE_WITH_VALUE,
TO_STRING,
VERSION,
APPLICATION_VERSION,
PERSISTED_DATA_VERSION,
PUT_ALL,
PUT_ALL_WITHOUT_ACC,
HASH_CODE,
@@ -126,6 +126,7 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
// used by the enterprise version
private int identifier;
@SuppressWarnings("UnusedDeclaration")
void identifier(int identifier) {
this.identifier = identifier;
}
@@ -135,8 +136,7 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
private final AtomicLong transactionID = new AtomicLong(0);
StatelessChronicleMap(@NotNull final StatelessMapConfig config,
@NotNull final ChronicleMapBuilder chronicleMapBuilder)
throws IOException {
@NotNull final ChronicleMapBuilder chronicleMapBuilder) {
this.config = config;
@@ -171,6 +171,21 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
inBuffer = allocateDirect(128).order(ByteOrder.nativeOrder());
inBytes = new ByteBufferBytes(inBuffer.slice());
versionCheck();
}
private void versionCheck() {
String serverVersion = serverApplicationVersion();
String clientVersion = clientVersion();
if (serverVersion.equals(clientVersion)) {
LOG.warn("The Chronicle Map Server and StalessClient are on different versions, " +
"although these version are backwards compatible, we" +
" suggest that you use the same version, server=" + serverApplicationVersion() + ", " +
"client=" + clientVersion);
}
}
@Override
@@ -272,6 +287,8 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
if (closeables != null) closeables.closeQuietly();
clientChannel = null;
}
}
/**
@@ -433,8 +450,19 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
}
@NotNull
public String version() {
return fetchObject(String.class, VERSION);
public String serverApplicationVersion() {
return fetchObject(String.class, APPLICATION_VERSION);
}
@NotNull
public String serverPersistedDataVersion() {
return fetchObject(String.class, PERSISTED_DATA_VERSION);
}
@SuppressWarnings("WeakerAccess")
@NotNull
public String clientVersion() {
return BuildVersion.readVersion();
}
public boolean isEmpty() {
@@ -516,16 +544,6 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
return fetchObject(PUT_MAPPED, key, unaryOperator);
}
/**
* estimates the size based on what been completed so far
*/
private long estimateSize(int numberOfEntries, int numberOfEntriesReadSoFar) {
assert outBytesLock.isHeldByCurrentThread();
assert !inBytesLock.isHeldByCurrentThread();
// we will back the size estimate on what we have so far
final double percentageComplete = (double) numberOfEntriesReadSoFar / (double) numberOfEntries;
return (long) ((double) outBytes.position() / percentageComplete);
}
private Bytes resizeBufferOutBuffer(int newCapacity) {
return resizeBufferOutBuffer(newCapacity, outBytes.position());
@@ -958,9 +976,9 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
try {
for (; ; ) {
if (clientChannel == null)
if (clientChannel == null) {
clientChannel = lazyConnect(config.timeoutMs(), config.remoteAddress());
}
try {
if (LOG.isDebugEnabled())
@@ -1196,7 +1214,7 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
long lagestEntrySoFar = 0;
long limitOfLast = 0;
private long limitOfLast = 0;
private void writeBytesToSocket(long timeoutTime) throws IOException {
@@ -1294,14 +1312,7 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
private ThreadLocalCopies writeKey(K key, ThreadLocalCopies copies) {
assert outBytesLock.isHeldByCurrentThread();
assert !inBytesLock.isHeldByCurrentThread();
long start = outBytes.position();
for (; ; ) {
return keyWriterWithSize.write(outBytes, key, copies);
}
return keyWriterWithSize.write(outBytes, key, copies);
}
@SuppressWarnings("UnusedReturnValue")
@@ -1309,8 +1320,6 @@ class StatelessChronicleMap<K, V> implements ChronicleMap<K, V>, Closeable, Clon
assert outBytesLock.isHeldByCurrentThread();
assert !inBytesLock.isHeldByCurrentThread();
return keyWriterWithSize.writeInLoop(outBytes, key, writer, copies);
}
@@ -1489,8 +1489,11 @@ class StatelessServerConnector<K, V> {
case TO_STRING:
return toString(writer.in(), sizeLocation);
case VERSION:
return version(writer.in(), sizeLocation);
case APPLICATION_VERSION:
return applicationVersion(writer.in(), sizeLocation);
case PERSISTED_DATA_VERSION:
return persistedDataVersion(writer.in(), sizeLocation);
case PUT_ALL:
return putAll(reader, writer.in(), sizeLocation, timestamp, identifier);
@@ -1615,12 +1618,31 @@ class StatelessServerConnector<K, V> {
@Nullable
private Work version(@NotNull Bytes writer, final long sizeLocation) {
private Work applicationVersion(@NotNull Bytes writer, final long sizeLocation) {
final long remaining = writer.remaining();
try {
String result = map.version();
String result = map.applicationVersion();
writer.writeObject(result);
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
}
assert remaining > 4;
writeSizeAndFlags(sizeLocation, false, writer);
return null;
}
@Nullable
private Work persistedDataVersion(@NotNull Bytes writer, final long sizeLocation) {
final long remaining = writer.remaining();
try {
String result = map.persistedDataVersion();
writer.writeObject(result);
} catch (Throwable e) {
return sendException(writer, sizeLocation, e);
@@ -73,7 +73,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
static final int MAX_ENTRY_OVERSIZE_FACTOR = 64;
private static final long serialVersionUID = 2L;
final Class<K> kClass;
final String mapVersion;
final String dataFileVersion;
final SizeMarshaller keySizeMarshaller;
final BytesReader<K> originalKeyReader;
final KI originalKeyInterop;
@@ -122,7 +122,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
kClass = keyBuilder.eClass;
keySizeMarshaller = keyBuilder.sizeMarshaller();
originalKeyReader = keyBuilder.reader();
mapVersion = BuildVersion.readVersion();
dataFileVersion = BuildVersion.readVersion();
originalKeyInterop = (KI) keyBuilder.interop();
@@ -178,12 +178,20 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
}
/**
* @return the version of Chronicle Map this instance was built with
* @return the version of Chronicle Map that was used to create the current data file
*/
String version() {
return mapVersion;
public String persistedDataVersion() {
return dataFileVersion;
}
/**
* @return the version of chronicle map that is currently running
*/
public String applicationVersion() {
return BuildVersion.readVersion();
}
final long segmentHash(long hash) {
return hashSplitting.segmentHash(hash);
}