You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2014/07/08 16:20:06 UTC
svn commit: r1608797 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/management/
main/java/org/apache/jackrabbit/oak/plugins/backup/
main/java/org/apache/jackrabbit/oak/plugins/blob/
main/java/org/apache/jackrabbit/oak/plug...
Author: mduerig
Date: Tue Jul 8 14:20:06 2014
New Revision: 1608797
URL: http://svn.apache.org/r1608797
Log:
OAK-1863: Generic operation tasks should be able to return specific results
Parametrise ManagementOperation on the return type of the passed task
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/management/ManagementOperation.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexAsyncReindex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/management/ManagementOperationTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/management/ManagementOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/management/ManagementOperation.java?rev=1608797&r1=1608796&r2=1608797&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/management/ManagementOperation.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/management/ManagementOperation.java Tue Jul 8 14:20:06 2014
@@ -21,8 +21,13 @@ package org.apache.jackrabbit.oak.manage
import static com.google.common.base.Objects.toStringHelper;
import static java.lang.Thread.currentThread;
-import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static javax.management.openmbean.SimpleType.INTEGER;
import static javax.management.openmbean.SimpleType.STRING;
import static org.apache.jackrabbit.oak.api.jmx.RepositoryManagementMBean.StatusCode;
@@ -40,6 +45,7 @@ import static org.apache.jackrabbit.oak.
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.management.openmbean.CompositeData;
@@ -59,7 +65,7 @@ import org.slf4j.LoggerFactory;
*
* @see org.apache.jackrabbit.oak.api.jmx.RepositoryManagementMBean
*/
-public class ManagementOperation extends FutureTask<Long> {
+public class ManagementOperation<R> extends FutureTask<R> {
private static final Logger LOG = LoggerFactory.getLogger(ManagementOperation.class);
private static final AtomicInteger idGen = new AtomicInteger();
@@ -73,55 +79,32 @@ public class ManagementOperation extends
* @param name informal name
* @param task task to execute for this operation
*/
- public ManagementOperation(String name, Callable<Long> task) {
- super(task);
- this.id = idGen.incrementAndGet();
- this.name = name;
- }
-
- private static final Callable<Long> NOP = new Callable<Long>() {
- @Override
- public Long call() throws Exception {
- return 0L;
- }
- };
-
- /**
- * Each instance of a {@code ManagementOperation} has an unique id
- * associated with it. This id is returned as a part of its
- * {@link #getStatus() status}
- *
- * @return id of this operation
- */
- public int getId() {
- return id;
- }
-
- /**
- * Informal name
- * @return name of this operation
- */
- public String getName() {
- return name;
+ public static <R> ManagementOperation<R> newManagementOperation(String name, Callable<R> task) {
+ return new ManagementOperation<R>(name, task);
}
/**
* An operation that is already done with the given {@code value}.
*
- * @param name name of the operation
- * @param value value returned by the operation
+ * @param name name of the operation
+ * @param result result returned by the operation
* @return a {@code ManagementOperation} instance that is already done.
*/
- public static ManagementOperation done(String name, final long value) {
- return new ManagementOperation("not started", NOP) {
+ public static <R> ManagementOperation<R> done(String name, final R result) {
+ return new ManagementOperation<R>("not started", new Callable<R>() {
+ @Override
+ public R call() throws Exception {
+ return result;
+ }
+ }) {
@Override
public boolean isDone() {
return true;
}
@Override
- public Long get() {
- return value;
+ public R get() {
+ return result;
}
@Override
@@ -137,6 +120,38 @@ public class ManagementOperation extends
}
/**
+ * Create a new {@code ManagementOperation} of the given name. The name
+ * is an informal value attached to this instance.
+ *
+ * @param name informal name
+ * @param task task to execute for this operation
+ */
+ private ManagementOperation(String name, Callable<R> task) {
+ super(task);
+ this.id = idGen.incrementAndGet();
+ this.name = name;
+ }
+
+ /**
+ * Each instance of a {@code ManagementOperation} has an unique id
+ * associated with it. This id is returned as a part of its
+ * {@link #getStatus() status}
+ *
+ * @return id of this operation
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
+ * Informal name
+ * @return name of this operation
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
* The {@link ManagementOperation.Status status} of this operation:
* <ul>
* <li>{@link Status#running(String) running} if the operation is currently
@@ -155,7 +170,7 @@ public class ManagementOperation extends
return failed(id, name + " cancelled");
} else if (isDone()) {
try {
- return succeeded(id, name + " completed in " + formatTime(get()));
+ return succeeded(id, name + " succeeded: " + get());
} catch (InterruptedException e) {
currentThread().interrupt();
return failed(id, name + " status unknown: " + e.getMessage());
@@ -168,10 +183,6 @@ public class ManagementOperation extends
}
}
- private static String formatTime(long nanos) {
- return MINUTES.convert(nanos, NANOSECONDS) + " minutes";
- }
-
@Override
public String toString() {
return toStringHelper(this)
@@ -265,6 +276,61 @@ public class ManagementOperation extends
}
/**
+ * Utility method for formatting a duration in nano seconds
+ * into a human readable string.
+ * @param nanos number of nano seconds
+ * @return human readable string
+ */
+ public static String formatTime(long nanos) {
+ TimeUnit unit = chooseUnit(nanos);
+ double value = (double) nanos / NANOSECONDS.convert(1, unit);
+ return String.format("%.4g %s", value, abbreviate(unit));
+ }
+
+ private static TimeUnit chooseUnit(long nanos) {
+ if (DAYS.convert(nanos, NANOSECONDS) > 0) {
+ return DAYS;
+ }
+ if (HOURS.convert(nanos, NANOSECONDS) > 0) {
+ return HOURS;
+ }
+ if (MINUTES.convert(nanos, NANOSECONDS) > 0) {
+ return MINUTES;
+ }
+ if (SECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return SECONDS;
+ }
+ if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return MILLISECONDS;
+ }
+ if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) {
+ return MICROSECONDS;
+ }
+ return NANOSECONDS;
+ }
+
+ private static String abbreviate(TimeUnit unit) {
+ switch (unit) {
+ case NANOSECONDS:
+ return "ns";
+ case MICROSECONDS:
+ return "\u03bcs"; // μs
+ case MILLISECONDS:
+ return "ms";
+ case SECONDS:
+ return "s";
+ case MINUTES:
+ return "min";
+ case HOURS:
+ return "h";
+ case DAYS:
+ return "d";
+ default:
+ throw new IllegalArgumentException(String.valueOf(unit));
+ }
+ }
+
+ /**
* Utility method for converting a {@code CompositeData} encoding
* of a status to a {@code Status} instance.
*
@@ -367,4 +433,5 @@ public class ManagementOperation extends
return result;
}
}
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java?rev=1608797&r1=1608796&r2=1608797&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java Tue Jul 8 14:20:06 2014
@@ -21,7 +21,9 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.System.nanoTime;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.Status.formatTime;
import static org.apache.jackrabbit.oak.management.ManagementOperation.done;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.newManagementOperation;
import static org.apache.jackrabbit.oak.plugins.backup.FileStoreBackup.backup;
import static org.apache.jackrabbit.oak.plugins.backup.FileStoreRestore.restore;
@@ -50,8 +52,8 @@ public class FileStoreBackupRestore impl
private final File file;
private final Executor executor;
- private ManagementOperation backupOp = done(BACKUP_OP_NAME, 0);
- private ManagementOperation restoreOp = done(RESTORE_OP_NAME, 0);
+ private ManagementOperation<String> backupOp = done(BACKUP_OP_NAME, "");
+ private ManagementOperation<String> restoreOp = done(RESTORE_OP_NAME, "");
/**
* @param store store to back up from or restore to
@@ -70,12 +72,12 @@ public class FileStoreBackupRestore impl
@Override
public synchronized CompositeData startBackup() {
if (backupOp.isDone()) {
- backupOp = new ManagementOperation("Backup", new Callable<Long>() {
+ backupOp = newManagementOperation("Backup", new Callable<String>() {
@Override
- public Long call() throws Exception {
+ public String call() throws Exception {
long t0 = nanoTime();
backup(store, file);
- return nanoTime() - t0;
+ return "Backup completed in " + formatTime(nanoTime() - t0);
}
});
executor.execute(backupOp);
@@ -91,12 +93,12 @@ public class FileStoreBackupRestore impl
@Override
public synchronized CompositeData startRestore() {
if (restoreOp.isDone()) {
- restoreOp = new ManagementOperation("Restore", new Callable<Long>() {
+ restoreOp = newManagementOperation("Restore", new Callable<String>() {
@Override
- public Long call() throws Exception {
+ public String call() throws Exception {
long t0 = nanoTime();
restore(file, store);
- return nanoTime() - t0;
+ return "Restore completed in " + formatTime(nanoTime() - t0);
}
});
executor.execute(restoreOp);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java?rev=1608797&r1=1608796&r2=1608797&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java Tue Jul 8 14:20:06 2014
@@ -21,7 +21,9 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.System.nanoTime;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.Status.formatTime;
import static org.apache.jackrabbit.oak.management.ManagementOperation.done;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.newManagementOperation;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
@@ -44,7 +46,7 @@ public class BlobGC implements BlobGCMBe
private final BlobGarbageCollector blobGarbageCollector;
private final Executor executor;
- private ManagementOperation gcOp = done(OP_NAME, 0);
+ private ManagementOperation<String> gcOp = done(OP_NAME, "");
/**
* @param blobGarbageCollector Blob garbage collector
@@ -61,12 +63,12 @@ public class BlobGC implements BlobGCMBe
@Override
public CompositeData startBlobGC() {
if (gcOp.isDone()) {
- gcOp = new ManagementOperation(OP_NAME, new Callable<Long>() {
+ gcOp = newManagementOperation(OP_NAME, new Callable<String>() {
@Override
- public Long call() throws Exception {
+ public String call() throws Exception {
long t0 = nanoTime();
blobGarbageCollector.collectGarbage();
- return nanoTime() - t0;
+ return "Blob gc completed in " + formatTime(nanoTime() - t0);
}
});
executor.execute(gcOp);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexAsyncReindex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexAsyncReindex.java?rev=1608797&r1=1608796&r2=1608797&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexAsyncReindex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/jmx/PropertyIndexAsyncReindex.java Tue Jul 8 14:20:06 2014
@@ -19,7 +19,9 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.System.nanoTime;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.Status.formatTime;
import static org.apache.jackrabbit.oak.management.ManagementOperation.done;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.newManagementOperation;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
@@ -42,11 +44,10 @@ public class PropertyIndexAsyncReindex i
private final AsyncIndexUpdate async;
private final Executor executor;
- private ManagementOperation arOp = done(OP_NAME, 0);
+ private ManagementOperation<String> arOp = done(OP_NAME, "");
/**
- * @param gc
- * Revision garbage collector
+ * @param async
* @param executor
* executor for running the garbage collection task
*/
@@ -60,16 +61,16 @@ public class PropertyIndexAsyncReindex i
@Override
public CompositeData startPropertyIndexAsyncReindex() {
if (arOp.isDone()) {
- arOp = new ManagementOperation(OP_NAME, new Callable<Long>() {
+ arOp = newManagementOperation(OP_NAME, new Callable<String>() {
@Override
- public Long call() throws Exception {
+ public String call() throws Exception {
long t0 = nanoTime();
boolean done = false;
while (!done) {
async.run();
done = async.isFinished();
}
- return nanoTime() - t0;
+ return "Reindex completed in " + formatTime(nanoTime() - t0);
}
});
executor.execute(arOp);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java?rev=1608797&r1=1608796&r2=1608797&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java Tue Jul 8 14:20:06 2014
@@ -20,8 +20,8 @@
package org.apache.jackrabbit.oak.spi.state;
import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.System.nanoTime;
import static org.apache.jackrabbit.oak.management.ManagementOperation.done;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.newManagementOperation;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
@@ -44,7 +44,7 @@ public class RevisionGC implements Revis
private final Runnable gc;
private final Executor executor;
- private ManagementOperation gcOp = done(OP_NAME, 0);
+ private ManagementOperation<String> gcOp = done(OP_NAME, "");
/**
* @param gc Revision garbage collector
@@ -61,12 +61,11 @@ public class RevisionGC implements Revis
@Override
public CompositeData startRevisionGC() {
if (gcOp.isDone()) {
- gcOp = new ManagementOperation(OP_NAME, new Callable<Long>() {
+ gcOp = newManagementOperation(OP_NAME, new Callable<String>() {
@Override
- public Long call() throws Exception {
- long t0 = nanoTime();
+ public String call() throws Exception {
gc.run();
- return nanoTime() - t0;
+ return "Revision GC initiated";
}
});
executor.execute(gcOp);
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/management/ManagementOperationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/management/ManagementOperationTest.java?rev=1608797&r1=1608796&r2=1608797&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/management/ManagementOperationTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/management/ManagementOperationTest.java Tue Jul 8 14:20:06 2014
@@ -28,6 +28,7 @@ import static java.util.concurrent.TimeU
import static org.apache.jackrabbit.oak.api.jmx.RepositoryManagementMBean.StatusCode.FAILED;
import static org.apache.jackrabbit.oak.api.jmx.RepositoryManagementMBean.StatusCode.RUNNING;
import static org.apache.jackrabbit.oak.api.jmx.RepositoryManagementMBean.StatusCode.SUCCEEDED;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.newManagementOperation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -60,15 +61,15 @@ public class ManagementOperationTest {
@Test(expected = IllegalStateException.class)
public void notStarted() throws ExecutionException, InterruptedException {
- ManagementOperation op = ManagementOperation.done("test", 42);
+ ManagementOperation<Integer> op = ManagementOperation.done("test", 42);
assertTrue(op.isDone());
- assertEquals(42, (long) op.get());
+ assertEquals(42, (int) op.get());
sameThreadExecutor().execute(op);
}
@Test
public void succeeded() throws InterruptedException, ExecutionException, TimeoutException {
- ManagementOperation op = new ManagementOperation("test", new Callable<Long>() {
+ ManagementOperation<Long> op = newManagementOperation("test", new Callable<Long>() {
@Override
public Long call() throws Exception {
return 42L;
@@ -76,27 +77,26 @@ public class ManagementOperationTest {
});
executor.execute(op);
- assertEquals(42, (long) op.get(5, SECONDS));
+ assertEquals(42L, (long) op.get(5, SECONDS));
assertTrue(op.isDone());
Status status = op.getStatus();
assertEquals(op.getId(), status.getId());
assertEquals(SUCCEEDED, status.getCode());
- assertTrue(status.getMessage().contains("test completed in"));
}
@Test
public void failed() throws InterruptedException, TimeoutException {
final Exception failure = new Exception("fail");
- ManagementOperation op = new ManagementOperation("test", new Callable<Long>() {
+ ManagementOperation<Void> op = newManagementOperation("test", new Callable<Void>() {
@Override
- public Long call() throws Exception {
+ public Void call() throws Exception {
throw failure;
}
});
executor.execute(op);
try {
- assertEquals(42, (long) op.get(5, SECONDS));
+ assertEquals(null, op.get(5, SECONDS));
fail("Expected " + failure);
} catch (ExecutionException e) {
assertEquals(failure, e.getCause());
@@ -112,12 +112,12 @@ public class ManagementOperationTest {
public void running() throws InterruptedException {
final LinkedBlockingDeque<Thread> thread = new LinkedBlockingDeque<Thread>(1);
- ManagementOperation op = new ManagementOperation("test", new Callable<Long>() {
+ ManagementOperation<Void> op = newManagementOperation("test", new Callable<Void>() {
@Override
- public Long call() throws Exception {
+ public Void call() throws Exception {
thread.add(currentThread());
sleep(100000);
- return 0L;
+ return null;
}
});
@@ -142,10 +142,10 @@ public class ManagementOperationTest {
@Test
public void cancelled() {
- ManagementOperation op = new ManagementOperation("test", new Callable<Long>() {
+ ManagementOperation<Void> op = newManagementOperation("test", new Callable<Void>() {
@Override
- public Long call() throws Exception {
- return 0L;
+ public Void call() throws Exception {
+ return null;
}
});