BASE has a simple system for sending signals between different parts of a system. This signalling system was initially developed to be able to kill plug-ins that a user for some reason wanted to abort. The signalling system as such is not limited to this and it can be used for other purposes as well. Signals can of course be handled internally in a single JVM but also sent externally to other JVM:s running on the same or a different computer. The transport mechanism for signals is decoupled from the actual handling of them. If you want to, you could implement a signal transporter that sends signal as emails and the target plug-in would never know.
The remainder of this section will focus mainly on the sending and transportation of signals. For more information about handling signals on the receiving end, see Section 26.7, “Enable support for aborting a running a plug-in”.
The signalling system is rather simple. An object that wish
to receieve signals must implement the
SignalTarget. It's only method
SignalHandler is an object that
knows what to do when a signal is delivered to it. The target object
may implement the
or use one of the existing handlers.
The difficult part here is to be aware that a signal is usually
delivered by a separate thread. The target object must be aware
of this and know how to handle multiple threads. As an example we
can use the
ThreadSignalHandler which simply
Thread.interrupt() to deliver a signal. The target
object that uses this signal handler it must know that it should check
Thread.interrupted() at regular intervals from the main
thread. If that method returns true, it means that the
signal has been delivered and the main thread should clean up and exit as
soon as possible.
Even if a signal handler could be given directly to the party
that may be interested in sending a signal to the target this
is not recommended. This would only work when sending signals
within the same virtual machine. The signalling system includes
SignalReceiver objects that are used
to decouple the sending of signals with the handling of signals. The
implementation usually comes in pairs, for example
Setting up the transport mechanism is usually a system responsibility.
Only the system know what kind of transport that is appropriate for it's current
setup. Ie. should signals be delievered by TCP/IP sockets, only internally, or
should a delivery mechanism based on web services be implemented?
If a system wants to receive signals it must create an appropriate
SignalReceiver object. Within BASE the
internal job queue set up it's own signalling system that can be used to
send signals (eg. kill) running jobs. The job agents do the same but uses
a different implementation. See the section called “Internal job queue section”
for more information about how to configure the internal job queue's
signal receiver. In both cases, there is only one signal receiver instance
active in the system.
Let's take the internal job queue as an example. Here is how it works:
When the internal job queue is started, it will also create a signal
receiver instance according to the settings in
The default is to create
which can only be used inside the same JVM. If needed, this can
be changed to a
SocketSignalReceiver or any other
When the job queue has found a plug-in to execute it will check if
it also implements the
interface. If it does, a signal handler is created and registered
with the signal receiver. This is actually done by the BASE core
which also makes sure that the the ID returned from the registration is
stored in the database together with the job item representing the
plug-in to execute.
Now, when the web client see's a running job which has a non-empty
signal transporter property, the Abort
button is activated. If the user clicks this button the BASE core
uses the information in the database to create
SignalTransporter object. This
is simply done by calling
The created signal transporter knows how to send a signal
to the signal receiver it was first registered with. When the
signal arrives at the receiver it will find the handler for it
SignalHandler.handleSignal(). This will in it's turn
trigger some action in the signal target which soon will abort what
it is doing and exit.