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

com.epam.deltix.util.progress.ExecutionMonitorImpl Maven / Gradle / Ivy

/*
 * Copyright 2021 EPAM Systems, Inc
 *
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. 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
 *
 *   http://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 com.epam.deltix.util.progress;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class ExecutionMonitorImpl implements ExecutionMonitor {

    private ArrayList children = new ArrayList();
    private ExecutionMonitorImpl parent;
    private Throwable error;

    private double progress;
    private long startTime = 0;
    private long endTime = 0;
    private long weight = 1;

    private boolean isAborted = false;

    private CountDownLatch counter;

    public ExecutionMonitorImpl() {
    }

    public double getProgress() {
        updateProgress();
        return progress;
    }

    public synchronized void setProgress(double v) {
        progress = v;
    }

    public synchronized long getStartTime() {
        return startTime;
    }

    public synchronized long getEndTime() {
        return endTime;
    }

    public void start() {
        counter = new CountDownLatch(children.size() + 1);
        startTime = System.currentTimeMillis();
    }

//    public synchronized boolean isAborted() {
//        return isAborted;
//    }

    public synchronized void abort(Throwable error) {
        if (isAborted)
            return;

        isAborted = true;
        endTime = System.currentTimeMillis();

        if (hasParent()) {
            parent.abort(error);
        }
        else {
            this.error = error;
            for (ExecutionMonitorImpl child : children)
                child.abort(error);
        }
    }

    public Throwable getError() {
        return error;
    }

    public synchronized void onComplete(ExecutionMonitorImpl child) {
        counter.countDown();
        if (counter.getCount() == 0)
            endTime = System.currentTimeMillis();
    }

    public synchronized void setComplete() {        
        setProgress(1.0);
        if (hasParent())
            parent.onComplete(this);
        else
            onComplete(null);
    }

    public boolean await() {
         try {
            while (true) {
                if (counter.await(1000, TimeUnit.MILLISECONDS))
                    return true;
                if (getStatus() == ExecutionStatus.Aborted)
                    return false;
            }

        } catch (InterruptedException e) {
            return false;
        }
    }

    public boolean await(long timeout) {
        try {
            long time = 0;
            while (time <= timeout) {
                time += 1000;
                if (counter.await(Math.min(1000, timeout - time), TimeUnit.MILLISECONDS))
                    return true;
                if (getStatus() == ExecutionStatus.Aborted)
                    return false;
            }
            return false;
            
        } catch (InterruptedException e) {
            return false;
        }
    }

    public synchronized long getWeight() {
        return weight;
    }

    public synchronized void setWeight(long weight) {
        this.weight = weight;
    }

    public synchronized void addMonitor(ExecutionMonitorImpl monitor) {
        children.add(monitor);
        monitor.parent = this;
    }

    private synchronized void updateProgress()
    {
        if (startTime == 0) // not started 
            return;

        double minProgress = -1;

        if (hasChildren())
        {
            progress = 0;
            double totalWeight = 0;

            for (ExecutionMonitorImpl child : children)
            {
                if (minProgress == -1 || child.progress < minProgress)
                    minProgress = child.progress;
                progress += (child.progress * child.weight);
                totalWeight += child.weight;
            }

            progress = (progress / totalWeight);
            //if (!CalculateMinChildEstimatedTime)
            minProgress = progress;
        }
        else
            minProgress = progress;

        // Make parent progress to update itself
        if (hasParent())
        {
            parent.updateProgress();
        }
//        else
//        {
//            // only parent sends Progress events
//            if (ProgressEvent != null && prevProgress != progress)
//            {
//                // Calculated Estimated time
//                TimeSpan estimatedTime = CalculateElapsedTime(minProgress);
//                //
//                ProgressEvent(this, new ProgressAgrs(estimatedTime, progress));
//            }
//
//            prevProgress = progress;
//        }
    }

    private boolean hasChildren() {
        return children.size() > 0;
    }

    private boolean hasParent() {
        return parent != null;
    }

    public synchronized ExecutionStatus getStatus() {
        if (isAborted)
            return error == null ? ExecutionStatus.Aborted : ExecutionStatus.Failed;
        if (counter != null && counter.getCount() > 0)
            return ExecutionStatus.Running;
        if (counter != null && counter.getCount() == 0)
            return ExecutionStatus.Completed;

        return ExecutionStatus.None;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy