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

play.jobs.Job Maven / Gradle / Ivy

There is a newer version: 1.5.0
Show newest version
package play.jobs;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import play.Invoker;
import play.Invoker.InvocationContext;
import play.Logger;
import play.Play;
import play.exceptions.JavaExecutionException;
import play.exceptions.PlayException;
import play.libs.F.Promise;
import play.libs.Time;

import com.jamonapi.Monitor;
import com.jamonapi.MonitorFactory;

/**
 * A job is an asynchronously executed unit of work
 * @param  The job result type (if any)
 */
public class Job extends Invoker.Invocation implements Callable {

    public static final String invocationType = "Job";
    
    protected ExecutorService executor;
    protected long lastRun = 0;
    protected boolean wasError = false;
    protected Throwable lastException = null;

    Date nextPlannedExecution = null;

    @Override
    public InvocationContext getInvocationContext() {
        return new InvocationContext(invocationType, this.getClass().getAnnotations());
    }
    
    /**
     * Here you do the job
     */
    public void doJob() throws Exception {
    }

    /**
     * Here you do the job and return a result
     */
    public V doJobWithResult() throws Exception {
        doJob();
        return null;
    }

    @Override
    public void execute() throws Exception {
    }

    /**
     * Start this job now (well ASAP)
     * @return the job completion
     */
    public Promise now() {
        final Promise smartFuture = new Promise();
        JobsPlugin.executor.submit(new Callable() {
            public V call() throws Exception {
                V result =  Job.this.call();
                smartFuture.invoke(result);
                return result;
            }
            
        });

        return smartFuture;
    }

    /**
     * Start this job in several seconds
     * @return the job completion
     */
    public Promise in(String delay) {
        return in(Time.parseDuration(delay));
    }

    /**
     * Start this job in several seconds
     * @return the job completion
     */
    public Promise in(int seconds) {
        final Promise smartFuture = new Promise();

        JobsPlugin.executor.schedule(new Callable() {

            public V call() throws Exception {
                V result =  Job.this.call();
                smartFuture.invoke(result);
                return result;
            }

        }, seconds, TimeUnit.SECONDS);

        return smartFuture;
    }

    /**
     * Run this job every n seconds
     */
    public void every(String delay) {
        every(Time.parseDuration(delay));
    }

    /**
     * Run this job every n seconds
     */
    public void every(int seconds) {
        JobsPlugin.executor.scheduleWithFixedDelay(this, seconds, seconds, TimeUnit.SECONDS);
    }

    // Customize Invocation
    @Override
    public void onException(Throwable e) {
        wasError = true;
        lastException = e;
        try {
            super.onException(e);
        } catch(Throwable ex) {
            Logger.error(ex, "Error during job execution (%s)", this);
        }
    }

    @Override
    public void run() {
        call();
    }

    public V call() {
        Monitor monitor = null;
        try {
            if (init()) {
                before();
                V result = null;

                try {
                    lastException = null;
                    lastRun = System.currentTimeMillis();
                    monitor = MonitorFactory.start(getClass().getName()+".doJob()");
                    result = doJobWithResult();
                    monitor.stop();
                    monitor = null;
                    wasError = false;
                } catch (PlayException e) {
                    throw e;
                } catch (Exception e) {
                    StackTraceElement element = PlayException.getInterestingStrackTraceElement(e);
                    if (element != null) {
                        throw new JavaExecutionException(Play.classes.getApplicationClass(element.getClassName()), element.getLineNumber(), e);
                    }
                    throw e;
                }
                after();
                return result;
            }
        } catch (Throwable e) {
            onException(e);
        } finally {
            if(monitor != null) {
                monitor.stop();
            }
            _finally();
        }
        return null;
    }

    @Override
    public void _finally() {
        super._finally();
        if (executor == JobsPlugin.executor) {
            JobsPlugin.scheduleForCRON(this);
        }
    }

    @Override
    public String toString() {
        return this.getClass().getName();
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy