All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.hal.flow.RepeatImpl Maven / Gradle / Ivy

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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy