Opened 17 years ago
Closed 17 years ago
#636 closed task (fixed)
Kill a running job
Reported by: | Johan Enell | Owned by: | Nicklas Nordborg |
---|---|---|---|
Priority: | major | Milestone: | BASE 2.6 |
Component: | core | Version: | |
Keywords: | Cc: |
Description (last modified by )
It should be possible for a user to kill a running job. The core sends a kill signal to a job and the job tells the plugin to end all processes(threads?) it has opened. If the job is running on a job agent this will have to be communicated through the a job agent.
This also means that a job agent should stop all jobs gracefully when the job agent itself is stopped (see #798).
I have been thinking a bit of this. It is not trivial since it requires that the plug-in is willing to be killed.
There are two main approaches:
1. Send a signal using the Thread class
- The BASE core is calling
Thread.interrupt()
on the thread that is executing the plug-in. - The plug-in must regularly check
Thread.interrupted()
. If this return true, it should stop what it is doing, rollback any changes and exit. - The call to
Thread.interrupt()
may also throw an InterruptedException if the plug-in is waiting in a blocking call.
There are a number of problems with this approach:
- Plug-ins must be aware of this and be coded to check the Thread.interrupted() status and be able to act on it. Most plug-ins today are not coded like this.
- If the plug-in is running on a job agent the kill signal must be communicated to the job agent first. The problem is that the only way to know which job agent a plug-in is running on is to ask all of them.
- Plug-ins may be running on something else that we don't know of.
Possible solutions to the above problems include:
- Create a tagging interface:
Killable
. If a plug-in implements this interface it must also promise to check and act on theThread.interrupted()
status. The core (and web client) will know if a plug-in is killable or not and doesn't have to put up a "Kill" button for those plug-ins that aren't killable.
- Store some kind of callback hook in the database. A callback hook is registered by the application that is starting the job (ie. internal job queue, job agent, etc.). If no hook has been registered for a job, it can't be killed (even if it implements the
Killable
interface). The core could provide simple implementations for "same-process-hook" and "external-process-hook".
2. Send a signal using the ProgressReporter
The idea is that since most plug-ins already regularly reports their progress, the same mechanism could be used to convey information in the other direction. This could be implemented as a flag in the Jobs table. The flag is set when a user clicks the "Kill" button in the web interface. When the progress reporter is about to update the status, it could just as well check this flag and throw an exception if it has been set.
The good thing with this solution is that it requires no (or very little) cooperation from the plug-in side or from the job agent side. Plug-ins should already be prepared to handle exceptions properly (rollback, cleanup and exit).
There are some problems also:
- Plug-ins are not required to use the progress reporter at all, and even if they do, there may be long intervals between the updates. For example, the
Base1PluginExecuter
doesn't update the progress when the external plug-in code is running, thus it would only be possible to kill this plug-in during the data export or import phase.
Note! The ability to kill a plug-in via the progress reporter could just be a special hook in solution 1 above. The Killable
interface could have one method where the core could query the plug-in if it should use the thread or the progress reporter to kill it.
Change History (13)
comment:1 by , 17 years ago
Milestone: | BASE 2.5 → BASE 2.6 |
---|---|
Summary: | Kill a runing job → Kill a running job |
comment:2 by , 17 years ago
Description: | modified (diff) |
---|
comment:3 by , 17 years ago
Milestone: | BASE 2.6 → BASE 2.x+ |
---|
comment:4 by , 17 years ago
Description: | modified (diff) |
---|
comment:5 by , 17 years ago
Milestone: | BASE 2.x+ → BASE 2.6 |
---|---|
Status: | new → assigned |
comment:6 by , 17 years ago
comment:7 by , 17 years ago
(In [4074]) References #636: Kill a running job
Infrastructure is now in place. Implementation for internal job queue has been tested and working. Still need:
- Implement signal transportation to job agents and via progress reporter
- Implement support in other core plug-ins (only import plug-ins based on FlatFileParser are working right now)
- Document everything
comment:8 by , 17 years ago
comment:10 by , 17 years ago
comment:11 by , 17 years ago
comment:12 by , 17 years ago
comment:13 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Reopen or create new tickets if there are problems or support for interruption is missing somewhere.
I'll start with this now. We had some discussions around the coffe table, and a lot of more good ideas came up. Options 1 is the foundation but has been extended a lot more and it will also be possible to cover case 2 with the solution. Here is some more information.
Signal
class and define theSignal.KILL
signal.Signalable
interface. The plug-ins are required to provide aSignalHandler
and information about which signals are supported.SignalHandler
is another interface and we will provide two implementations. AThreadSignalHandler
that usesThread.interrupt
and aProgressReporterSignalHandler
that uses the progress reporter.SignalTransporter
andSignalReceiver
. The implementation comes in pairs, the transporters knows how to send a signal to a receiver. It can be in the local VM or through a socket or through web services. We will provide an implementation that uses sockets:SocketSignalTransporter
andSocketSignalReceiver
When a plug-in is started the following happens:
Signalable
interface.SignalHandler
is created.SignalReceiver
provided by the queue manager.When the user wants to kill a job the following happens:
SignalTransporter
object is createdThread.interrupt()