|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.schmant.run.TaskExecutor
public class TaskExecutor
The TaskExecutor
is used for running independent tasks in parallel
execution threads. This often gives a nice speedup of the build since the
build host's resources are used more efficiently, but it comes with the cost
of added complexity for build scripts.
The added complexity mostly comes from that it is no longer possible to
assume that task A will run before task B. If task B depends on the results
of task A, task B must be scheduled with that information stored in a
TaskDependency
.
It is also no longer possible to assume that task A has been run when task B
is being configured. As a consequence, those of task B's properties
that are dependent on the result from task A must be configured using
different kinds of FutureEntity
:s and
FutureProperty
:s.
The task executor uses an internal queue to keep track of scheduled jobs that
have not been run. By default, a job that has all of its dependencies met
will be added at a random position in the queue. Jobs are thus run in a
random order, which is a naïve way of trying to automatically balance I/O
bound jobs with CPU bound jobs. To run jobs in the order that they are
scheduled, call setUseFifoQueue(boolean)
with a true
argument.
A task executor must be started by calling start()
before any tasks
may be added to it. When all tasks have been added, call waitFor()
to wait until all tasks have been run, or waitFor(TaskDependency)
to
wait until a certain dependency is met. After using a TaskExecutor
(regardless of if all tasks were successful or not), always call
shutdown()
to terminate all build threads. See the JavaScript
example below.
var te = new TaskExecutor(); ...configure the TaskExecutor te.start(); try { ... add tasks te.waitFor(); } finally { te.shutdown(); }
A TaskExecutor
can only be used once. Once waitFor()
(or
shutdown()
has been called, no more tasks can be added to it.
The TaskExecutor
defaults to using only one build thread. To use more
threads, call setNumberOfThreads(int)
before starting it.
Read the Schmant manual and see the task executor-using examples in the task factory reference for more information on how to use a task executor.
Field Summary | |
---|---|
static int |
DEFAULT_NUMBER_OF_THREADS
A very safe default (1). |
Constructor Summary | |
---|---|
TaskExecutor()
Create the task executor and register it with the TaskExecutors
class. |
|
TaskExecutor(boolean register)
Create the task executor and optionally register it with the TaskExecutors class. |
Method Summary | |
---|---|
TaskDependency |
add(Object o)
Add a Task , a TaskFactory or a closure to the task
executor. |
TaskDependency |
add(Object o,
Object deps)
Add a Task , TaskFactory or a closure with one or several
dependencies to the executor. |
void |
awaitTermination(long time,
TimeUnit tu)
Wait the specified time, maximum for the task executor to terminate. |
protected ThreadPoolExecutor |
createExecutor()
Create the thread pool Executor that is used for running tasks. |
protected ThreadFactory |
createThreadFactory()
Create a thread factory for the Executor . |
protected BlockingQueue<Runnable> |
createWorkQueue()
Create the work queue for the Executor . |
int |
getNumberOfThreads()
Get the maximum number of threads for the task executor. |
ReadOnlyTaskExecutorStatus |
getStatus()
Return a read only view of the task executor's status. |
boolean |
isUseFifoQueue()
Does this task executor use a FIFO queue for scheduling tasks? |
TaskExecutor |
setLogDependencies(boolean b)
By setting this to true , information about dependencies are
logged to level INFO. |
TaskExecutor |
setNumberOfThreads(int no)
Set the maximum number of threads for the task executor. |
TaskExecutor |
setUseFifoQueue(boolean b)
Use a FIFO (first in - first out) queue for tasks? The default value of this property is, false , meaning that a queue enqueuing tasks in
random order is used. |
void |
shutdown()
Call this to shut down the task executor before all tasks have been executed. |
void |
shutdownNow()
Call this to shut down the task executor before all tasks have been executed. |
TaskExecutor |
start()
Start the task executor. |
void |
update(Observable obs,
Object o)
This is called when a dependency is met. |
void |
waitFor()
Wait for all tasks to finish. |
void |
waitFor(TaskDependency td)
Wait for a specific task dependency to complete. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final int DEFAULT_NUMBER_OF_THREADS
Constructor Detail |
---|
public TaskExecutor()
TaskExecutors
class.
TaskExecutor(boolean)
public TaskExecutor(boolean register)
TaskExecutors
class.
This constructor should only be used by test classes.
register
- Should the task executor be registered with the
TaskExecutors
class? If this is set to false
, the build
script must ensure that the task executor is shut down on all code paths.
It is safest to set this to true
.TaskExecutor()
Method Detail |
---|
public ReadOnlyTaskExecutorStatus getStatus()
public TaskExecutor setLogDependencies(boolean b)
true
, information about dependencies are
logged to level INFO.
b
- Should dependency information be logged?
this
.public TaskExecutor setNumberOfThreads(int no) throws IllegalStateException
start()
:ing.
no
- The maximum number of executor threads.
this
.
IllegalStateException
- If the task executor is started.public int getNumberOfThreads()
public TaskExecutor setUseFifoQueue(boolean b)
false
, meaning that a queue enqueuing tasks in
random order is used. This is believed to give slightly better
performance since tasks with different performance profiles will be
executed in parallel. If this is set to true
, a FIFO queue will
be used and tasks will be executed in the order that they were added to
the queue (in the order that they were scheduled and in the order that
all their dependencies were met).
Both queue types only execute tasks whose dependencies have been met.
b
- Should the queue be FIFO?
this
public boolean isUseFifoQueue()
true
if this task executor uses a FIFO queue.setUseFifoQueue(boolean)
protected BlockingQueue<Runnable> createWorkQueue()
Executor
. If the useFifo
property is set to true
, a LinkedBlockingQueue
is
returned, if not, a PriorityBlockingQueue
without any Comparator
set is returned (the tasks will be executed in random order).
Both queues are unlimited in their capacities.
Subclasses may override this to change the behavior.
setUseFifoQueue(boolean)
protected ThreadFactory createThreadFactory()
Executor
. The default is to
create a TaskExecutorThreadFactory
. This can be overridden by
subclasses to create other kinds of queues.
protected ThreadPoolExecutor createExecutor()
Executor
that is used for running tasks.
public TaskExecutor start()
After scheduling all tasks, call waitFor()
to wait for all tasks
to complete.
this
public void shutdown()
Executor.shutdown()
, this will let all
currently running tasks finish before the task executor is terminated.
After calling this method, call awaitTermination(long, TimeUnit)
to wait for the executor to finish.
waitFor()
public void shutdownNow()
Executor.shutdown()
, this will let all
currently running tasks finish before the task executor is terminated.
After calling this method, call awaitTermination(long, TimeUnit)
to wait for the executor to finish.
waitFor()
public void awaitTermination(long time, TimeUnit tu) throws InterruptedException
waitFor()
instead.
time
- The maximum time to wait.tu
- The time unit.
InterruptedException
- If the task executor has not terminated when
the time is up.public void waitFor(TaskDependency td) throws InterruptedException, TaskFailedException
td
- The dependency.
InterruptedException
- If the thread that called this method is
interrupted while waiting.
TaskFailedException
- On other errors.public void waitFor() throws InterruptedException
shutdown()
.
InterruptedException
- If the task executor is interrupted.public TaskDependency add(Object o) throws SchmantException
Task
, a TaskFactory
or a closure to the task
executor.
o
- The task, task factory or closure.
SchmantException
- If the added object is neither a task, a task
factory or a closure.public TaskDependency add(Object o, Object deps) throws SchmantException
Task
, TaskFactory
or a closure with one or several
dependencies to the executor.
o
- The task, task factory or closure.deps
- One or several dependencies. This may be a single
TaskDependency
object or an array or Collection
of objects. The object list is flattened using a FlatteningList
.
SchmantException
- If the added object is neither a task, a task
factory or a closure.public void update(Observable obs, Object o)
TaskDependency
, the thread calling this method must hold the
dependency's satisfied state lock.
update
in interface Observer
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |