/**
 * OW2 Specifications
 * Copyright (C) 2007 Bull S.A.S.
 * Contact: easybeans@objectweb.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: WorkManager.java 4359 2008-12-10 10:24:40Z sauthieg $
 * --------------------------------------------------------------------------
 */

package javax.resource.spi.work;
 
/**
 * This interface models a {@link WorkManager} which provides a facility
 * to submit {@link Work} instances for execution. This frees the user
 * from having to create Java threads directly to do work. Further, this
 * allows efficient pooling of thread resources and more control over thread
 * usage. The various stages in Work processing are:<br/>
 * <ul>
 *   <li>work submit: A {@link Work} instance is being submitted for
 *   execution. The {@link Work} instance could either be accepted or
 *   rejected with a {@link WorkRejectedException} set to an appropriate
 *   error code.</li>
 *   <li>work accepted: The submitted {@link Work} instance has been
 *   accepted. The accepted {@link Work} instance could either start
 *   execution or could be rejected again with a {@link WorkRejectedException}
 *   set to an appropriate error code. There is no guarantee on when
 *   the execution would start unless a start timeout duration is
 *   specified. When a start timeout is specified, the {@link Work}
 *   execution must be started within the specified duration (not a
 *   real-time guarantee), failing which a {@link WorkRejectedException}
 *   set to an error code (<code>WorkRejected.TIMED_OUT</code>) is thrown.</li>
 *   <li>work rejected: The {@link Work} instance has been rejected. The
 *   {@link Work} instance could be rejected during {@link Work} submittal
 *   or after the {@link Work} instance has been accepted (but before
 *   {@link Work} instance starts execution). The rejection could be due
 *   to internal factors or start timeout expiration. A {@link WorkRejectedException}
 *   with an appropriate error code (indicates the reason) is thrown in
 *   both cases.</li>
 *   <li>work started: The execution of the {@link Work} instance has
 *   started. This means that a thread has been allocated for its
 *   execution. But this does not guarantee that the allocated thread
 *   has been scheduled to run on a CPU resource. Once execution is
 *   started, the allocated thread sets up an appropriate execution
 *   context (transaction , security, etc) and calls <code>Work.run()</code>.
 *   Note, any exception thrown during execution context setup or
 *   <code>Work.run()</code> leads to completion of processing.</li>
 *   <li>work completed: The execution of the {@link Work} has been
 *   completed. The execution could complete with or without an exception.
 *   The {@link WorkManager} catches any exception thrown during {@link Work}
 *   processing (which includes execution context setup), and wraps it
 *   with a {@link WorkCompletedException}.</li>
 * <ul>
 * @version 1.0
 * @author Guillaume Sauthier
 */
public interface WorkManager {

    /**
     * A constant to indicate timeout duration. A zero timeout value
     * indicates an action be performed immediately.
     */
    static final long IMMEDIATE = 0L;
    
    /**
     * A constant to indicate timeout duration. A maximum timeout value
     * indicates that an action be performed arbitrarily without any time
     * constraint.
     */
    static final long INDEFINITE = 9223372036854775807L;
    
    /**
     * A constant to indicate an unknown start delay duration or other
     * unknown values.
     */
    static final long UNKNOWN = -1L;
    
    /**
     * Accepts a Work instance for processing. This call blocks until
     * the Work instance completes execution. There is no guarantee on
     * when the accepted Work instance would start execution ie.,
     * there is no time constraint to start execution.
     * @param work The unit of work to be done. Could be long or short-lived.
     * @throws WorkException generic exception
     * @throws WorkRejectedException indicates that a Work instance has been
     *         rejected from further processing. This can occur due to
     *         internal factors.
     * @throws WorkCompletedException indicates that a Work instance has
     *         completed execution with an exception.
     */
    void doWork(Work work) throws WorkException;
    
    /**
     * Accepts a Work instance for processing. This call blocks until the
     * Work instance completes execution.
     * @param work The unit of work to be done. Could be long or short-lived.
     * @param startTimeout a time duration (in milliseconds) within which the
     *        execution of the Work instance must start. Otherwise, the Work
     *        instance is rejected with a WorkRejectedException set to an
     *        appropriate error code (WorkRejectedException.TIMED_OUT).
     *        Note, this does not offer real-time guarantees.
     * @param execContext an object containing the execution context with
     *        which the submitted Work instance must be executed.
     * @param workListener an object which would be notified when the various
     *        Work processing events (work accepted, work rejected, work
     *        started, work completed) occur.
     * @throws WorkException generic exception
     * @throws WorkRejectedException indicates that a Work instance has been
     *         rejected from further processing. This can occur due to
     *         internal factors or start timeout expiration.
     * @throws WorkCompletedException indicates that a Work instance has
     *         completed execution with an exception.
     */
    void doWork(Work work,
                long startTimeout,
                ExecutionContext execContext,
                WorkListener workListener) throws WorkException;
    
    /**
     * Accepts a Work instance for processing. This call blocks until the
     * Work instance starts execution but not until its completion. There
     * is no guarantee on when the accepted Work instance would start
     * execution ie., there is no time constraint to start execution.
     * @param work The unit of work to be done. Could be long or short-lived.
     * @return the time elapsed (in milliseconds) from Work  acceptance
     *         until start of execution. Note, this does not offer real-time
     *         guarantees. It is valid to return -1, if the actual start
     *         delay duration is unknown.
     * @throws WorkException generic exception
     * @throws WorkRejectedException indicates that a Work instance has
     *         been rejected from further processing. This can occur due
     *         to internal factors.
     */
    long startWork(Work work) throws WorkException;
    
    /**
     * Accepts a Work instance for processing. This call blocks until the
     * Work instance starts execution but not until its completion. There is
     * no guarantee on when the accepted Work instance would start execution
     * ie., there is no time constraint to start execution.
     * @param work The unit of work to be done. Could be long or short-lived.
     * @param startTimeout a time duration (in milliseconds) within which the
     *        execution of the Work instance must start. Otherwise, the Work
     *        instance is rejected with a WorkRejectedException set to an
     *        appropriate error code (WorkRejectedException.TIMED_OUT). Note,
     *        this does not offer real-time guarantees.
     * @param execContext an object containing the execution context with which
     *        the submitted Work instance must be executed.
     * @param workListener an object which would be notified when the various
     *        Work processing events (work accepted, work rejected, work started,
     *        work completed) occur.
     * @return the time elapsed (in milliseconds) from Work  acceptance until
     *         start of execution. Note, this does not offer real-time guarantees.
     *         It is valid to return -1, if the actual start delay duration is unknown.
     * @throws WorkException generic exception
     * @throws WorkRejectedException indicates that a Work instance has been
     *         rejected from further processing. This can occur due to internal
     *         factors or start timeout expiration.
     */
    long startWork(Work work,
                   long startTimeout,
                   ExecutionContext execContext,
                   WorkListener workListener) throws WorkException;
    
    /**
     * Accepts a Work instance for processing. This call does not block and returns
     * immediately once a Work  instance has been accepted for processing. There is
     * no guarantee on when the submitted Work instance would start execution ie.,
     * there is no time constraint to start execution.
     * @param work The unit of work to be done. Could be long or short-lived.
     * @throws WorkException generic exception
     * @throws WorkRejectedException indicates that a Work instance has been
     *         rejected from further processing. This can occur due to internal
     *         factors.
     */
    void scheduleWork(Work work) throws WorkException;
    
    /**
     * Accepts a Work instance for processing. This call does not block and returns
     * immediately once a Work  instance has been accepted for processing.
     * @param work The unit of work to be done. Could be long or short-lived.
     * @param startTimeout a time duration (in milliseconds) within which the
     *        execution of the Work instance must start. Otherwise, the Work
     *        instance is rejected with a WorkRejectedException set to an appropriate
     *        error code (WorkRejectedException.TIMED_OUT). Note, this does not
     *        offer real-time guarantees.
     * @param execContextan object containing the execution context with which
     *        the submitted Work instance must be executed.
     * @param workListener an object which would be notified when the various Work
     *        processing events (work accepted, work rejected, work started, work
     *        completed) occur.
     * @throws WorkException generic exception
     * @throws WorkRejectedException indicates that a Work instance has been rejected
     *         from further processing. This can occur due to internal factors.
     */
    void scheduleWork(Work work,
                     long startTimeout,
                     ExecutionContext execContext,
                     WorkListener workListener) throws WorkException;
    
    
}
