SOLR-13423: Upgrade RRD4j to version 3.5.

This commit is contained in:
Andrzej Bialecki 2019-04-24 12:01:05 +02:00
parent 80d3ac8709
commit 170f5fb7a3
8 changed files with 171 additions and 23 deletions

View File

@ -285,7 +285,7 @@ org.restlet.jee.version = 2.3.0
/org.restlet.jee/org.restlet = ${org.restlet.jee.version} /org.restlet.jee/org.restlet = ${org.restlet.jee.version}
/org.restlet.jee/org.restlet.ext.servlet = ${org.restlet.jee.version} /org.restlet.jee/org.restlet.ext.servlet = ${org.restlet.jee.version}
/org.rrd4j/rrd4j = 3.2 /org.rrd4j/rrd4j = 3.5
/org.simpleframework/simple-xml = 2.7.1 /org.simpleframework/simple-xml = 2.7.1

View File

@ -296,6 +296,8 @@ Other Changes
* SOLR-13400: Replace Observable pattern in TransientSolrCoreCache (Erick Erickson) * SOLR-13400: Replace Observable pattern in TransientSolrCoreCache (Erick Erickson)
* SOLR-13423: Upgrade RRD4j to version 3.5. (ab)
================== 8.0.0 ================== ================== 8.0.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

View File

@ -25,6 +25,7 @@ import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -754,7 +755,7 @@ public class MetricsHistoryHandler extends RequestHandlerBase implements Permiss
} }
if (factory.exists(name)) { if (factory.exists(name)) {
// get a throwaway copy (safe to close and discard) // get a throwaway copy (safe to close and discard)
RrdDb db = new RrdDb(URI_PREFIX + name, true, factory); RrdDb db = RrdDb.getBuilder().setBackendFactory(factory).setReadOnly(true).setPath(new URI(URI_PREFIX + name)).build();
SimpleOrderedMap<Object> status = new SimpleOrderedMap<>(); SimpleOrderedMap<Object> status = new SimpleOrderedMap<>();
status.add("status", getDbStatus(db)); status.add("status", getDbStatus(db));
status.add("node", nodeName); status.add("node", nodeName);

View File

@ -56,7 +56,7 @@ public class SolrRrdBackend extends RrdByteArrayBackend implements Closeable {
try { try {
SyncData syncData = factory.getData(path); SyncData syncData = factory.getData(path);
if (syncData != null) { if (syncData != null) {
this.buffer = syncData.data; setBuffer(syncData.data);
this.lastModifiedTime = syncData.timestamp; this.lastModifiedTime = syncData.timestamp;
} }
} catch (IOException e) { } catch (IOException e) {
@ -75,9 +75,10 @@ public class SolrRrdBackend extends RrdByteArrayBackend implements Closeable {
readOnly = true; readOnly = true;
factory = null; factory = null;
this.lastModifiedTime = other.lastModifiedTime; this.lastModifiedTime = other.lastModifiedTime;
byte[] otherBuffer = other.buffer; byte[] otherBuffer = other.getBuffer();
buffer = new byte[otherBuffer.length]; byte[] newBuffer = new byte[otherBuffer.length];
System.arraycopy(otherBuffer, 0, buffer, 0, otherBuffer.length); System.arraycopy(otherBuffer, 0, newBuffer, 0, otherBuffer.length);
super.setBuffer(newBuffer);
} }
public boolean isReadOnly() { public boolean isReadOnly() {
@ -88,6 +89,11 @@ public class SolrRrdBackend extends RrdByteArrayBackend implements Closeable {
return lastModifiedTime; return lastModifiedTime;
} }
private void markDirty() {
lastModifiedTime = TimeUnit.MILLISECONDS.convert(factory.getTimeSource().getEpochTimeNs(), TimeUnit.NANOSECONDS);
dirty = true;
}
@Override @Override
protected void write(long offset, byte[] bytes) throws IOException { protected void write(long offset, byte[] bytes) throws IOException {
if (readOnly || closed) { if (readOnly || closed) {
@ -96,14 +102,144 @@ public class SolrRrdBackend extends RrdByteArrayBackend implements Closeable {
lock.lock(); lock.lock();
try { try {
super.write(offset, bytes); super.write(offset, bytes);
lastModifiedTime = TimeUnit.MILLISECONDS.convert(factory.getTimeSource().getEpochTimeNs(), TimeUnit.NANOSECONDS); markDirty();
dirty = true;
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
public SyncData getSyncData() { @Override
protected void writeShort(long offset, short value) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.writeShort(offset, value);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected void writeInt(long offset, int value) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.writeInt(offset, value);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected void writeLong(long offset, long value) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.writeLong(offset, value);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected void writeDouble(long offset, double value) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.writeDouble(offset, value);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected void writeDouble(long offset, double value, int count) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.writeDouble(offset, value, count);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected void writeDouble(long offset, double[] values) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.writeDouble(offset, values);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected void writeString(long offset, String value, int length) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.writeString(offset, value, length);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected boolean isDirty() {
return dirty;
}
@Override
protected void setBuffer(byte[] buffer) {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.setBuffer(buffer);
markDirty();
} finally {
lock.unlock();
}
}
@Override
protected void setLength(long length) throws IOException {
if (readOnly || closed) {
return;
}
lock.lock();
try {
super.setLength(length);
markDirty();
} finally {
lock.unlock();
}
}
public SyncData getSyncDataAndMarkClean() {
if (readOnly || closed) { if (readOnly || closed) {
return null; return null;
} }
@ -113,18 +249,17 @@ public class SolrRrdBackend extends RrdByteArrayBackend implements Closeable {
// hold a lock to block writes so that we get consistent data // hold a lock to block writes so that we get consistent data
lock.lock(); lock.lock();
try { try {
byte[] bufferCopy = new byte[buffer.length]; byte[] oldBuffer = getBuffer();
System.arraycopy(buffer, 0, bufferCopy, 0, buffer.length); byte[] bufferCopy = new byte[oldBuffer.length];
System.arraycopy(oldBuffer, 0, bufferCopy, 0, oldBuffer.length);
return new SyncData(bufferCopy, lastModifiedTime); return new SyncData(bufferCopy, lastModifiedTime);
} finally { } finally {
// reset the dirty flag
dirty = false;
lock.unlock(); lock.unlock();
} }
} }
public void markClean() {
dirty = false;
}
@Override @Override
public void close() throws IOException { public void close() throws IOException {
super.close(); super.close();

View File

@ -152,6 +152,20 @@ public class SolrRrdBackendFactory extends RrdBackendFactory implements SolrClos
} }
} }
@Override
public URI getCanonicalUri(URI uri) {
return uri;
}
// @Override
// protected URI getRootUri() {
// try {
// return new URI("solr", null, null, null);
// } catch (URISyntaxException e) {
// throw new RuntimeException("Impossible error", e);
// }
// }
//
/** /**
* Open (or get) a backend. * Open (or get) a backend.
* @param path backend path (without URI scheme) * @param path backend path (without URI scheme)
@ -336,7 +350,7 @@ public class SolrRrdBackendFactory extends RrdBackendFactory implements SolrClos
log.debug("-- maybe sync backends: " + backends.keySet()); log.debug("-- maybe sync backends: " + backends.keySet());
Map<String, SolrRrdBackend.SyncData> syncDatas = new HashMap<>(); Map<String, SolrRrdBackend.SyncData> syncDatas = new HashMap<>();
backends.forEach((path, backend) -> { backends.forEach((path, backend) -> {
SolrRrdBackend.SyncData syncData = backend.getSyncData(); SolrRrdBackend.SyncData syncData = backend.getSyncDataAndMarkClean();
if (syncData != null) { if (syncData != null) {
syncDatas.put(backend.getPath(), syncData); syncDatas.put(backend.getPath(), syncData);
} }
@ -367,12 +381,6 @@ public class SolrRrdBackendFactory extends RrdBackendFactory implements SolrClos
} catch (SolrServerException e) { } catch (SolrServerException e) {
log.warn("Error committing RRD data updates", e); log.warn("Error committing RRD data updates", e);
} }
syncDatas.forEach((path, data) -> {
SolrRrdBackend backend = backends.get(path);
if (backend != null) {
backend.markClean();
}
});
} catch (IOException e) { } catch (IOException e) {
log.warn("Error sending RRD data updates", e); log.warn("Error sending RRD data updates", e);
} }

View File

@ -27,6 +27,7 @@ import org.apache.solr.common.params.CollectionAdminParams;
import org.apache.solr.common.util.Pair; import org.apache.solr.common.util.Pair;
import org.apache.solr.common.util.TimeSource; import org.apache.solr.common.util.TimeSource;
import org.apache.solr.common.util.Utils; import org.apache.solr.common.util.Utils;
import org.apache.solr.util.LogLevel;
import org.apache.solr.util.MockSearchableSolrClient; import org.apache.solr.util.MockSearchableSolrClient;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -42,6 +43,7 @@ import org.rrd4j.core.Sample;
/** /**
* *
*/ */
@LogLevel("org.apache.solr.metrics.rrd=DEBUG")
public class SolrRrdBackendFactoryTest extends SolrTestCaseJ4 { public class SolrRrdBackendFactoryTest extends SolrTestCaseJ4 {
private SolrRrdBackendFactory factory; private SolrRrdBackendFactory factory;

View File

@ -1 +0,0 @@
8d480d5aa87b3d358862b78d6fa3660396220dc7

View File

@ -0,0 +1 @@
540c946b471dc915b0beb7c07069e3946665ef5d