CTX
- The context type to use, can by any Component
, service
or POJO.H
- The handle type used to reference a job.public interface JobBus<CTX,H>
extends org.refcodes.component.HandleLookup<H,org.refcodes.command.Undoable<CTX,?,?>>, org.refcodes.component.ProgressHandle<H>, org.refcodes.component.ResetHandle<H>, org.refcodes.component.FlushHandle<H>
JobBus
makes use of the Undoable
pattern and is used to
execute job (Undoable
) instances by a client. The client may be the
business logic creating a Undoable
(job) to be executed.
The JobBus
takes a client's Undoable
(job) to be executed.
For asynchronous execution a handle is passed back to the client with which
the state (in progress, failure, success) of the Undoable
(job) can
be determined as well as the Undoable
's (job's) result be requested
(the actual result or an exception in case of failure). For synchronous
operation, the JobBus
halts your invoking thread till either the
result is (available and) passed back or an exception is thrown.
To invoke a Undoable
(job), the JobBus
, being the invoker,
passes the context to the Undoable
(job) and requests the
Undoable
(job) to apply its operation with regard to the context.
As you can see, the JobBus
is responsible for managing the context
and for invoking the Undoable
(job). This decouples the business
logic from the knowledge on how to retrieve a context or where the
Undoable
is actually being executed (more on this later).
As of the implemented handle paradigm, the job-bus may be used by various
parties without revealing their Undoable
(job) instances (to each
other) being processed by the JobBus
.
DISTRIBUTED ENVIRONMENT
The operation a Undoable
(job) represents is atomic, encapsulated in
an object and applied to a context. The JobBus
may distribute the
Undoable
(job) to a different JobBus
, probably located on a
different machine, where the Undoable
(job) eventually gets executed.
The result of the Undoable
(job) execution then gets passed back to
the originating JobBus
, which then passes it back to the client.
(this scenario assumes that a) your command (job) is serializable as well as b) your result is serializable)
DO/UNDO STACK
As a Undoable
(job) may also undo things it has done (executed), an
undo stack may hold your application's Undoable
(job) instances in
the order of their execution. Using to undo stack in reverse order, the
executed operations can be undone one-by-one or in batch.
COMPONENT / SERVICE
In a Component
or service driven environment, the JobBus
may
be one of the services centrally being set up and configured as well as
centrally being provided to your application's Component
(service)
instances. So you have one point of Undoable
(job) execution;
application wide; providing the benefits of the JobBus
in a
transparent manner to your application.
Modifier and Type | Method and Description |
---|---|
H |
execute(org.refcodes.command.Undoable<CTX,?,?> aJob)
Executes the given job.
|
<RET,E extends Exception> |
execute(org.refcodes.command.Undoable<CTX,RET,E> aJob,
BiConsumer<RET,E> aResultConsumer)
Executes the given job and invokes the provides
BiConsumer lambda
(closure) upon finished execution. |
<RET,E extends Exception> |
execute(org.refcodes.command.Undoable<CTX,RET,E> aJob,
Consumer<RET> aResultConsumer)
Executes the given job and invokes the provided
Consumer lambda
(closure) upon finished execution. |
<E extends Exception> |
getException(H aHandle)
Returns the exception of the job in case it terminated with an error.
|
<RET> RET |
getResult(H aHandle)
Returns the result of the job as the result of executing the job.
|
<JOB extends org.refcodes.command.Undoable<CTX,RET,?>,RET> |
getResult(JOB aJob)
Executes the job and waits for the job's result or an exception.
|
<JOB extends org.refcodes.command.Undoable<CTX,RET,?>,RET> |
getResult(JOB aJob,
long aTimeoutInMs)
Executes the job and waits for the job's result or an exception or till
the timeout has been reached.
|
boolean |
hasException(H aHandle)
Determines whether the job identified by the given handle ended with an
exception (instead of a regular result).
|
boolean |
hasResult(H aHandle)
Determines whether the job identified by the given handle has a regular
result (instead of an exception).
|
boolean |
isExecuted(H aHandle)
Determines whether the job has been executed.
|
void |
waitForExecution(H aHandle)
Waits till the job identified by the given handle finished execution by
regularly terminating or by throwing an exception.
|
void |
waitForExecution(H aHandle,
long aTimeoutInMs)
Waits till the job identified by the given handle finished execution by
regularly terminating or by throwing an exception or till the timeout has
been reached.
|
H execute(org.refcodes.command.Undoable<CTX,?,?> aJob)
aJob
- The job to be executed.<RET,E extends Exception> void execute(org.refcodes.command.Undoable<CTX,RET,E> aJob, Consumer<RET> aResultConsumer)
Consumer
lambda
(closure) upon finished execution. The parameter is passed in case we
have an ordinary result, an exceptual situation is "ignored" as the
Consumer
will not be invoked in such a case.
In case you have to take action upon an exceptional situation, then use
the execute(Undoable, BiConsumer)
method.aJob
- The job to be executed.aResultConsumer
- The Consumer
lambda to be invoked upon
finished execution.<RET,E extends Exception> void execute(org.refcodes.command.Undoable<CTX,RET,E> aJob, BiConsumer<RET,E> aResultConsumer)
BiConsumer
lambda
(closure) upon finished execution. The first parameter is passed in case
we have an ordinary result, the second one is passed in case we have an
exceptional situation. Either the one parameter or the other one is
passed, never both of them at the same invocation! In case both arguments
are null, then your job has returned null. Consider using the
Optional
to be returned by your job. Though consider that the
Optional
is NOT serializable which could cause problems with
remote job execution!
In case you do not have to take action upon an exceptional situation,
then use the execute(Undoable, Consumer)
method.aJob
- The job to be executed.aResultConsumer
- The BiConsumer
lambda to be invoked upon
finished execution.void waitForExecution(H aHandle) throws org.refcodes.component.UnknownHandleRuntimeException
aHandle
- The handle associated with the provided job.org.refcodes.component.UnknownHandleRuntimeException
- in case the handle is not unknown.void waitForExecution(H aHandle, long aTimeoutInMs) throws org.refcodes.component.UnknownHandleRuntimeException, org.refcodes.component.HandleTimeoutRuntimeException
HandleTimeoutRuntimeException
is thrown to abort the waiting
loop. This is especially useful when a remote connection is used to
managed a distributed JobBus
infrastructure and due to connection
issues, wait time would be endless.
The handle my be used to determine if there was an exception or not and
to retrieve the result or in case of an exception the exception object.aHandle
- The handle associated with the provided job.aTimeoutInMs
- The timeout to wait at most even when execution did
not finish. In case the timeout has been reached before execution
was finished, then a HandleTimeoutRuntimeException
is
thrown to abort the waiting loop.org.refcodes.component.UnknownHandleRuntimeException
- Thrown in case the handle is not
unknown.org.refcodes.component.HandleTimeoutRuntimeException
- Thrown in case the timeout was
reached before execution finished.<JOB extends org.refcodes.command.Undoable<CTX,RET,?>,RET> RET getResult(JOB aJob) throws org.refcodes.command.NoResultAvailableRuntimeException
RET
- The return type of the Undoable
's proceedings.aJob
- The job to executeorg.refcodes.command.NoResultAvailableRuntimeException
- in case a job has been executed
which never delivers a result or which terminated with an
exception. Use hasException(Object)
and
hasResult(Object)
to clarify which state your
Undoable
(job) is in.<JOB extends org.refcodes.command.Undoable<CTX,RET,?>,RET> RET getResult(JOB aJob, long aTimeoutInMs) throws org.refcodes.command.NoResultAvailableRuntimeException, org.refcodes.component.HandleTimeoutRuntimeException
HandleTimeoutRuntimeException
is thrown to abort the waiting
loop. This is especially useful when a remote connection is used to
managed a distributed JobBus
infrastructure and due to connection
issues, wait time would be endless.RET
- The return type of the Undoable
's proceedings.aJob
- The job to executeaTimeoutInMs
- The timeout to wait at most even when execution did
not finish. In case the timeout has been reached before execution
was finished, then a HandleTimeoutRuntimeException
is
thrown to abort the waiting loop.org.refcodes.command.NoResultAvailableRuntimeException
- in case a job has been executed
which never delivers a result or which terminated with an
exception. Use hasException(Object)
and
hasResult(Object)
to clarify which state your
Undoable
(job) is in.org.refcodes.component.HandleTimeoutRuntimeException
boolean isExecuted(H aHandle) throws org.refcodes.component.UnknownHandleRuntimeException
aHandle
- The handle associated to the job in question.org.refcodes.component.UnknownHandleRuntimeException
- in case the handle is not unknown.boolean hasResult(H aHandle) throws org.refcodes.component.UnknownHandleRuntimeException, org.refcodes.command.NotYetExecutedRuntimeException
aHandle
- The handle associated to the job in question.org.refcodes.command.NotYetExecutedRuntimeException
- in case the job has not been
executed yetorg.refcodes.component.UnknownHandleRuntimeException
- in case the handle is not unknown.boolean hasException(H aHandle) throws org.refcodes.component.UnknownHandleRuntimeException, org.refcodes.command.NotYetExecutedRuntimeException
aHandle
- The handle associated to the job in question.org.refcodes.command.NotYetExecutedRuntimeException
- in case the job has not been
executed yet.org.refcodes.component.UnknownHandleRuntimeException
- in case the handle is not unknown.<RET> RET getResult(H aHandle) throws org.refcodes.component.UnknownHandleRuntimeException, org.refcodes.command.NotYetExecutedRuntimeException, org.refcodes.command.NoResultAvailableRuntimeException
RET
- As of convenience, the return type of the Undoable
instance's proceedings. CAUTION: As the handle does not permit
insight on the Undoable
(job) instance's return type, you
may end up with a class cast exception in case you do not make
sure that the result is of the expected type aHandle
- The handle associated to the job in question.org.refcodes.command.NoResultAvailableRuntimeException
- in case the job did not provide
a result after execution.org.refcodes.command.NotYetExecutedRuntimeException
- in case the job has not been
executed yet.org.refcodes.component.UnknownHandleRuntimeException
- in case the handle is not unknown.<E extends Exception> E getException(H aHandle) throws org.refcodes.component.UnknownHandleRuntimeException, org.refcodes.command.NotYetExecutedRuntimeException, org.refcodes.command.NoExceptionAvailableRuntimeException
RET
- As of convenience, the exception type of the
Undoable
instance's erroneous proceedings. CAUTION: As the
handle does not permit insight on the Undoable
(job)
instance's exception type, you may end up with a class cast
exception in case you do not make sure that the exception is of
the expected type aHandle
- The handle associated to the job in question.org.refcodes.command.NoExceptionAvailableRuntimeException
- in case the job did not
provide an exception after execution.org.refcodes.command.NotYetExecutedRuntimeException
- in case the job has not been
executed yet.org.refcodes.component.UnknownHandleRuntimeException
- in case the handle is not unknown.Copyright © 2017. All rights reserved.