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

org.hcjf.cloud.timer.CloudTimerTask Maven / Gradle / Ivy

package org.hcjf.cloud.timer;

import org.hcjf.cloud.Cloud;
import org.hcjf.log.Log;
import org.hcjf.properties.SystemProperties;
import org.hcjf.service.ServiceSession;
import org.hcjf.service.ServiceThread;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @author javaito
 *
 */
public abstract class CloudTimerTask implements Runnable {

    private final String name;
    private final Lock lock;
    private final Condition condition;
    private final Map timerTaskMap;

    private final String mapName;
    private final String lockName;
    private final String conditionName;

    public CloudTimerTask(String name) {
        this.name = name;

        mapName = SystemProperties.get(SystemProperties.Cloud.TimerTask.MAP_SUFFIX_NAME) + name;
        lockName = SystemProperties.get(SystemProperties.Cloud.TimerTask.LOCK_SUFFIX_NAME) + name;
        conditionName = SystemProperties.get(SystemProperties.Cloud.TimerTask.CONDITION_SUFFIX_NAME) + name;

        lock = Cloud.getLock(lockName);
        condition = Cloud.getCondition(conditionName, lock);
        timerTaskMap = Cloud.getMap(SystemProperties.get(SystemProperties.Cloud.TimerTask.MAP_NAME));
    }

    /**
     * Implementation of the life cycle of the distributed timer task.
     */
    @Override
    public final void run() {
        Long lastExecution;
        Long currentExecution;
        Long delay;
        while(!Thread.currentThread().isInterrupted()) {
            //Try to block the task with the same name in the cloud.
            lock.lock();
            try {
                //Verify if the delay value of the task is grater than the min value of
                //the system properties. If not bigger then the value is truncated to the min
                //value of the system properties.
                delay = getDelay();
                if (delay < SystemProperties.getLong(SystemProperties.Cloud.TimerTask.MIN_VALUE_OF_DELAY)) {
                    delay = SystemProperties.getLong(SystemProperties.Cloud.TimerTask.MIN_VALUE_OF_DELAY);
                }

                //Get the timestamp of the las execution of the task in the cloud.
                lastExecution = timerTaskMap.get(mapName);
                if (lastExecution == null) {
                    //If the last execution timestamp is null then this value is
                    //initialized with the current system timestamp.
                    lastExecution = System.currentTimeMillis();
                    timerTaskMap.put(mapName, lastExecution);
                }

                //Recalculate the delay value based on the last execution timestamp and
                //the current system timestamp.
                delay = delay - (System.currentTimeMillis() - lastExecution);

                //Sleep the task with the recalculated delay value.
                condition.await(delay, TimeUnit.MILLISECONDS);

                //If the current timestamp is equals than the las execution timestamp then
                //this threat is the first in get the lock, for this is in charge to execute the task.
                currentExecution = timerTaskMap.get(mapName);
                if (currentExecution.equals(lastExecution)) {
                    ServiceSession previousSession = ((ServiceThread) Thread.currentThread()).getSession();
                    //Execute the custom logic
                    try {
                        Log.d(System.getProperty(SystemProperties.Cloud.LOG_TAG),"Starting timer task execution %s", name);
                        ((ServiceThread) Thread.currentThread()).setSession(ServiceSession.getSystemSession());
                        onRun();
                    } catch (Throwable ex) {
                        Log.d(System.getProperty(SystemProperties.Cloud.LOG_TAG),"Starting timer task error execution %s", name);
                        onError(ex);
                    } finally {
                        ((ServiceThread) Thread.currentThread()).setSession(previousSession);
                        Log.d(System.getProperty(SystemProperties.Cloud.LOG_TAG),"Ending timer task execution %s", name);
                    }
                    //Update the las execution value.
                    timerTaskMap.put(mapName, System.currentTimeMillis());
                }
            } catch (InterruptedException ex) {
                break;
            } catch (Exception ex){
                ex.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    /**
     * Return the delay value to each cycle of the task.
     * @return Delay value.
     */
    protected abstract Long getDelay();

    /**
     * Custom logic implementation.
     */
    protected abstract void onRun();

    /**
     * Implements this method in order to process the error.
     * @param throwable Throwable instance.
     */
    protected void onError(Throwable throwable) {}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy