org.jboss.hal.flow.RepeatImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hal-flow Show documentation
Show all versions of hal-flow Show documentation
Async Flow based on Promise API
The newest version!
/*
* Copyright 2022 Red Hat
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.hal.flow;
import java.util.function.Predicate;
import elemental2.promise.Promise;
import elemental2.promise.Promise.PromiseExecutorCallbackFn.RejectCallbackFn;
import elemental2.promise.Promise.PromiseExecutorCallbackFn.ResolveCallbackFn;
import static elemental2.dom.DomGlobal.clearInterval;
import static elemental2.dom.DomGlobal.clearTimeout;
import static elemental2.dom.DomGlobal.setInterval;
import static elemental2.dom.DomGlobal.setTimeout;
class RepeatImpl extends FlowRunner implements Repeat {
private final Task task;
private Predicate predicate;
private boolean failFast;
private long interval;
private long timeout;
private int iterations;
private int index;
private String lastFailure;
private double timeoutHandle;
private double intervalHandle;
RepeatImpl(final C context, final Task task) {
super(context, 1);
this.task = task;
this.predicate = __ -> true;
this.failFast = DEFAULT_FAIL_FAST;
this.interval = DEFAULT_INTERVAL;
this.timeout = DEFAULT_TIMEOUT;
this.iterations = DEFAULT_ITERATIONS;
this.index = 0;
this.lastFailure = null;
this.timeoutHandle = 0;
this.intervalHandle = 0;
}
// ------------------------------------------------------ repeat API
@Override
public Repeat while_(final Predicate predicate) {
this.predicate = predicate;
return this;
}
@Override
public Repeat failFast(final boolean failFast) {
this.failFast = failFast;
return this;
}
@Override
public Repeat interval(final long interval) {
this.interval = interval;
return this;
}
@Override
public Repeat timeout(final long timeout) {
this.timeout = timeout;
return this;
}
@Override
public Repeat iterations(final int iterations) {
this.iterations = iterations;
return this;
}
// ------------------------------------------------------ run
@Override
Promise run() {
return new Promise<>((resolve, reject) -> {
timeoutHandle = setTimeout(__ -> cancel(reject, TIMEOUT_ERROR), timeout);
if (!predicate.test(context)) {
finish(resolve, context);
}
until(resolve, reject);
});
}
private void until(ResolveCallbackFn resolve, RejectCallbackFn reject) {
intervalHandle = setInterval(__ -> {
if (failFast && lastFailure != null) {
cancel(reject, lastFailure);
} else {
task.apply(context)
.then(c -> {
index++;
c.progress.tick();
if (areWeDone(c)) {
finish(resolve, c);
}
return null;
})
.catch_(error -> {
lastFailure = String.valueOf(error);
if (failFast) {
cancel(reject, lastFailure);
}
return null;
});
}
}, interval);
}
// ------------------------------------------------------ helper methods
private boolean areWeDone(C context) {
if (iterations > 0) {
return index == iterations || !predicate.test(context);
} else {
return !predicate.test(context);
}
}
private void finish(ResolveCallbackFn resolve, C context) {
cleanup();
context.progress.finish();
resolve.onInvoke(context);
}
private void cancel(RejectCallbackFn reject, String reason) {
cleanup();
reject.onInvoke(reason);
}
private void cleanup() {
clearInterval(intervalHandle);
clearTimeout(timeoutHandle);
}
}