Opened 10 years ago

Closed 10 years ago

#892 closed enhancement (fixed)

Abort long-running queries

Reported by: nicklas Owned by: nicklas
Priority: minor Milestone: BASE 2.6
Component: core Version:
Keywords: Cc:


A problem that became visible when working with #636 (Kill a running job) was that the core doesn't support very much of interrupting the current work. This is specially true for queries against the database. Even though an analysis plug-in supports the abort signal, it may currently be locked in a long-running query against the database. This means that the job isn't interrupted until after the query has finished. This can take several minutes. Since there is no indication of what is going on in the user interface, this will probably confuse users and make them think that the "Abort" functionality sucks and is not working.

Parts of the core that may take a long time to execute should also be prepared to abort if they are interrupted. First out is the part that is executing queries against the database. This will not be trivial. We have to consider cases when we use Hibernate and cases when we use the dynamic database.

Queries against the main database is done through Hibernate. All calls are passing through only a few places (in HibernateUtil?). Hibernate exposes the Session.cancelQuery() method which can probably be used.

Queries against the dynamic database we create our own Statement or PreparedStatement? objects. They have a cancel() method, which can probably be used.

The tricky part is to be able to call those methods, since nothing of this is exposed to anyone outside the core and only little to anything inside the core. Maybe we can add a cancelQuery() to DbControl?. This would work for the Hibernate case since we have access to the current session from this. Getting it to work for the dynamic part will probably require adding a lot of code to register the currently executing statement, etc. Another problem is how we know which DbControl? to cancel when all we have to begin with is the worker thread of the plug-in.

Another possible solution is to let the worker thread start a new thread for the query. The worker thread then calls Thread.join() to wait for the query thread to finish. If nothing spectacular happens all is well and the result is returned. If the worker thread is interrupted it will exit the Thread.join() call with an InterruptedException?. This can be catched and the proper cancel() method can be called on the query thread. The good thing with this solution is that only the internal part of the core where queries are started need to be modified. The drawback is that a lot of extra threads will be created.

Change History (3)

comment:1 Changed 10 years ago by nicklas

  • Owner changed from everyone to nicklas
  • Status changed from new to assigned

comment:2 Changed 10 years ago by nicklas

(In [4119]) References #892: Abort long-running queries

Implemented a way to intterupt executing queries by redirecting all query activity through QueryExecutor?. This class uses features from the java.util.concurrent package. Currently, we only use this with queries against the dynamic database. It should not be very difficult to add support for Hibernate queries as well, but I don't know if there is any need for the extra overhead, since most of the time the Hibernate queries doesn't take long time.

The current implementation uses a simple unbounded thread pool. In the future, we should consider adding some configuration options for this.

comment:3 Changed 10 years ago by nicklas

  • Resolution set to fixed
  • Status changed from assigned to closed

DataQuery:s also has the potential of taking long time. This includes for example queries against the reporter and feature tables. But there is a problem since those queries are using a StatelessSession? and this doesn't have a cancelQuery() method as the regular sessions. In other words, there seems to be no way to cancel queries which use a StatelessSession?. I have added ticket #920 so we don't forget about this and will now close this one.

Note: See TracTickets for help on using tickets.