Skip to content

Commit

Permalink
OAK-6009: Simplify cancellation of compaction by timeout
Browse files Browse the repository at this point in the history
Add timeout functionality to CancelCompactionSupplier

git-svn-id: https://svn.apache.org/repos/asf/jackrabbit/oak/trunk@1789459 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
mduerig committed Mar 30, 2017
1 parent af43913 commit be1d09d
Showing 1 changed file with 19 additions and 34 deletions.
Expand Up @@ -796,7 +796,7 @@ synchronized CompactionResult compact() {
compactionMonitor.init(GC_COUNT.get(), gcEntry.getRepoSize(), gcEntry.getNodes(), initialSize);

SegmentNodeState before = getHead();
Supplier<Boolean> cancel = new CancelCompactionSupplier(FileStore.this);
CancelCompactionSupplier cancel = new CancelCompactionSupplier(FileStore.this);
SegmentWriter writer = segmentWriterBuilder("c")
.with(cacheManager)
.withGeneration(newGeneration)
Expand Down Expand Up @@ -852,7 +852,8 @@ synchronized CompactionResult compact() {
Stopwatch forceWatch = Stopwatch.createStarted();

cycles++;
after = forceCompact(writer, or(cancel, timeOut(forceTimeout, SECONDS)));
cancel.timeOutAfter(forceTimeout, SECONDS);
after = forceCompact(writer, cancel);
success = after != null;
if (success) {
gcListener.info("TarMK GC #{}: compaction succeeded to force compact remaining commits " +
Expand Down Expand Up @@ -892,38 +893,6 @@ synchronized CompactionResult compact() {
}
}

/**
* @param duration
* @param unit
* @return {@code Supplier} instance which returns true once the time specified in
* {@code duration} and {@code unit} has passed.
*/
private Supplier<Boolean> timeOut(final long duration, @Nonnull final TimeUnit unit) {
return new Supplier<Boolean>() {
final long deadline = currentTimeMillis() + MILLISECONDS.convert(duration, unit);
@Override
public Boolean get() {
return currentTimeMillis() > deadline;
}
};
}

/**
* @param supplier1
* @param supplier2
* @return {@code Supplier} instance that returns {@code true} iff {@code supplier1} returns
* {@code true} or otherwise {@code supplier2} returns {@code true}.
*/
private Supplier<Boolean> or(
@Nonnull Supplier<Boolean> supplier1,
@Nonnull Supplier<Boolean> supplier2) {
if (supplier1.get()) {
return Suppliers.ofInstance(true);
} else {
return supplier2;
}
}

private SegmentNodeState compact(NodeState head, SegmentWriter writer, Supplier<Boolean> cancel)
throws IOException {
if (gcOptions.isOffline()) {
Expand Down Expand Up @@ -1137,17 +1106,29 @@ void cancel() {
* the space was never sufficient to begin with), compaction is considered
* canceled. Furthermore when the file store is shutting down, compaction is
* considered canceled.
* Finally the cancellation can be triggered by a timeout that can be set
* at any time.
*/
private class CancelCompactionSupplier implements Supplier<Boolean> {
private final FileStore store;

private String reason;
private volatile long deadline;

public CancelCompactionSupplier(@Nonnull FileStore store) {
cancelled = false;
this.store = store;
}

/**
* Set a timeout for cancellation. Setting a different timeout cancels
* a previous one that did not yet elapse. Setting a timeout after
* cancellation took place has no effect.
*/
public void timeOutAfter(final long duration, @Nonnull final TimeUnit unit) {
deadline = currentTimeMillis() + MILLISECONDS.convert(duration, unit);
}

@Override
public Boolean get() {
// The outOfDiskSpace and shutdown flags can only transition from
Expand All @@ -1169,6 +1150,10 @@ public Boolean get() {
reason = "Cancelled by user";
return true;
}
if (deadline > 0 && currentTimeMillis() > deadline) {
reason = "Timeout after " + deadline/1000 + " seconds";
return true;
}
return false;
}

Expand Down

0 comments on commit be1d09d

Please sign in to comment.