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

com.devebot.opflow.OpflowTask Maven / Gradle / Ivy

There is a newer version: 0.3.1
Show newest version
package com.devebot.opflow;

import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author drupalex
 */
public class OpflowTask {
    
    public interface Listener {
        public void handleEvent();
    }
    
    public static class Countdown {
        private final Lock lock = new ReentrantLock();
        private Condition idle = lock.newCondition();
        private int total = 0;
        private int count = 0;
        private long waiting = 1000;
        
        public Countdown() {
            this(0);
        }

        public Countdown(int total) {
            this.reset(total);
        }
        
        public Countdown(int total, long waiting) {
            this.reset(total, waiting);
        }

        public final void reset(int total) {
            this.idle = lock.newCondition();
            this.count = 0;
            this.total = total;
        }
        
        public final void reset(int total, long waiting) {
            this.reset(total);
            this.waiting = waiting;
        }

        public void check() {
            lock.lock();
            try {
                count++;
                if (count >= total) idle.signal();
            } finally {
                lock.unlock();
            }
        }

        public void bingo() {
            lock.lock();
            try {
                while (count < total) idle.await();
            } catch(InterruptedException ie) {
            } finally {
                lock.unlock();
            }
            if (waiting > 0) {
                try {
                    Thread.sleep(waiting);
                } catch (InterruptedException ie) {}
            }
        }

        public int getCount() {
            return count;
        }
    }
    
    public interface Timeoutable {
        long getTimeout();
        long getTimestamp();
        void raiseTimeout();
    }
    
    public static class TimeoutMonitor {
        private final static Logger LOG = LoggerFactory.getLogger(TimeoutMonitor.class);
        private final OpflowLogTracer logTracer;
        private long timeout;
        private final String monitorId;
        private final Map tasks;
        private final int interval;
        private final Timer timer = new Timer(true);
        private final TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                if (tasks == null || tasks.isEmpty()) return;
                long current = OpflowUtil.getCurrentTime();
                OpflowLogTracer logTask = logTracer.branch("timestamp", current);
                if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logTask
                        .put("taskListSize", tasks.size())
                        .put("threadCount", Thread.activeCount())
                        .text("Monitor[${monitorId}].run(), tasks: ${taskListSize}, threads: ${threadCount}")
                        .stringify());
                for (String key : tasks.keySet()) {
                    if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTask
                            .put("taskId", key)
                            .text("run() examine the task[${taskId}]")
                            .stringify());
                    Timeoutable task = tasks.get(key);
                    if (task == null) continue;
                    long _timeout = task.getTimeout();
                    if (_timeout <= 0) _timeout = timeout;
                    if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTask
                            .put("taskId", key)
                            .put("monitorTimeout", timeout)
                            .put("taskTimeout", task.getTimeout())
                            .put("timeout", _timeout)
                            .text("run() task[${taskId}]'s timeout: ${taskTimeout} | ${monitorTimeout} ~ ${timeout}")
                            .stringify());
                    if (_timeout > 0) {
                        long diff = current - task.getTimestamp();
                        if (diff > _timeout) {
                            tasks.remove(key);
                            task.raiseTimeout();
                            if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTask
                                    .put("taskId", key)
                                    .put("diff", diff)
                                    .put("timeout", _timeout)
                                    .text("run() task[${taskId}] is timeout (diff: ${diff} > ${timeout}), rejected")
                                    .stringify());
                        } else {
                            if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTask
                                    .put("taskId", key)
                                    .text("run() task[${taskId}] is good, keep running")
                                    .stringify());
                        }
                    }
                }
            }
        };
        
        public TimeoutMonitor(Map tasks) {
            this(tasks, 2000);
        }
        
        public TimeoutMonitor(Map tasks, int interval) {
            this(tasks, interval, 1000l);
        }
        
        public TimeoutMonitor(Map tasks, int interval, long timeout) {
            this(tasks, interval, timeout, null);
        }
        
        public TimeoutMonitor(Map tasks, int interval, long timeout, String monitorId) {
            this.tasks = tasks;
            this.interval = interval;
            this.timeout = timeout;
            this.monitorId = (monitorId != null) ? monitorId : OpflowUtil.getLogID();
            logTracer = OpflowLogTracer.ROOT.branch("monitorId", this.monitorId);
            if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logTracer
                    .put("interval", this.interval)
                    .put("timeout", this.timeout)
                    .text("Monitor[${monitorId}] has been created with interval: ${interval}, timeout: ${timeout}")
                    .stringify());
        }
        
        public void start() {
            if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logTracer
                    .text("Monitor.start()")
                    .stringify());
            if (interval > 0) {
                timer.scheduleAtFixedRate(timerTask, 0, interval);
                if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logTracer
                        .put("interval", interval)
                        .text("Monitor has been started with interval: ${interval}")
                        .stringify());
            } else {
                if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logTracer
                        .put("interval", interval)
                        .text("Monitor is not available. undefined interval")
                        .stringify());
            }
        }
        
        public void stop() {
            if (OpflowLogTracer.has(LOG, "debug")) LOG.debug(logTracer
                    .text("Monitor.stop()")
                    .stringify());
            timer.cancel();
            timer.purge();
        }
    }
    
    public static class TimeoutWatcher extends Thread {
        private final static Logger LOG = LoggerFactory.getLogger(TimeoutWatcher.class);
        private final OpflowLogTracer logTracer;
        
        public TimeoutWatcher(String requestId, long max, Listener listener) {
            this.requestId = requestId;
            logTracer = OpflowLogTracer.ROOT.branch("requestId", this.requestId);
            if (max > 0) {
                this.max = max;
            }
            this.listener = listener;
        }

        public TimeoutWatcher(String taskId, long interval, long max, Listener listener) {
            this(taskId, max, listener);
            if (interval > 0) {
                this.interval = interval;
            }
        }

        private String requestId;
        private Listener listener;
        private long interval = 1000;
        private long max = 0;
        private long count = 0;
        private boolean done = false;

        @Override
        public void run() {
            while(count < max && !done) {
                try {
                    Thread.sleep(interval);
                    count += interval;
                    if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTracer
                            .text("TimeoutWatcher is interrupted")
                            .stringify());
                    if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTracer
                            .put("count", count)
                            .put("max", max)
                            .text("TimeoutWatcher.listener is requested")
                            .stringify());
                    if (count >= max) {
                        if (this.listener != null) {
                            listener.handleEvent();
                        }
                        if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTracer
                                .text("TimeoutWatcher.listener is requested")
                                .stringify());
                        this.interrupt();
                    }
                } catch(InterruptedException ie) {}
            }
        }

        public void check() {
            this.count = 0;
        }

        public void close() {
            this.done = true;
            if (OpflowLogTracer.has(LOG, "trace")) LOG.trace(logTracer
                    .text("TimeoutWatcher is closed gracefully")
                    .stringify());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy