Eclipse Jobs And JDBC


Today I refactored one long action of our product in order to use jobs.

In one of our custom views the end user can click on an “Open Statistics Views” action. This action asks to a Statistics module to compute some stats. These statistics are computed from a local database and the computation can take several seconds (up to ~30s). Before today all the action was performed directly in the UI thread. I am already earing most of you saying: “What ??!!! You are freezing the UI for 30 seconds ??? Yes I am (shame on me), and yes I know it’s bad and that’s why I decided to change that.

The first thing I looked to fix this issue was Eclipse’s Jobs. The API is straightforward and quite easy to learn. Quickly I had my call to statistic module performing stats computation running in a Job using an IProgressMonitor of type UNKNOWN.
Here is the code

StatJob statJob = new StatJob("Computing Statistics");
		statJob.setUser(false);
		statJob.addJobChangeListener(new JobChangeAdapter() {
			public void done(final IJobChangeEvent event) {
				if (event.getResult().isOK()) {
                    // UI update using job run method result
					PlatformUI.getWorkbench().getDisplay().syncExec(
							new Runnable() {
								public void run() {
									StatJob statJob = (StatJob) event.getJob();
									setInput(statJob.sessionStat);
								}
							});
				}
			}
		});
		statJob.schedule();

Notice the use of an IJobChangeListener in order to update the view when the Job’s work will be done.

This solution is better than performing stats computation in the UI thread but there is still an “issue”: what about progress feedback to the user ??. The UNKNOWN type only says to the user: “Something is happening, I am working but I can’t tell you when I’ll finish”

Since the stats are performed using mainly 2 SQL requests through JDBC I can only divide my Job in 2 amount of work . Moreover one of this two SQL request is longer than the other so dividing 30 seconds of work into 2 seconds and 28 seconds will not help the user.

After browsing the JDBC Api and mainly the Statement’s one “I discovered” the cancel() method documented as following: “Cancels this Statement object if both the DBMS and driver support aborting an SQL statement. This method can be used by one thread to cancel a statement that is being executed by another thread.

First attempts using this methods didn’t succeeded and resulted in SQLException. I’ll investigate more on the subject (for info we are using an SQLite database with Zentus JDBC driver) but I would be interested about the way you provide progress feedback  to the user when accessing database ?

Manu

Advertisements
This entry was posted in Uncategorized by Manuel. Bookmark the permalink.

3 thoughts on “Eclipse Jobs And JDBC

  1. We have similar problems where we search in Documentum for certain objects.

    We cannot update the progress bar accordingly while the search is running (there is no callback mechanism…), but can set a detail task name where we give the user a hint what is happening and that this may take a long time…

    I think, this is better than no progress bar :-)

  2. We have similar issues with DTP and have since the beginning. The biggest issue is what you’re already encountering – the synchronous nature of JDBC calls. So we can’t cancel a long-running connect or SQL operation either.

    What we ended up doing however was breaking the process into smaller bits and that helped the responsiveness in the UI. In the Data Source Explorer tree for example, we have a little animated node that churns while in the background we’re waiting for results to come back.

  3. You’ve a Client/Server architecture and you seem to have the ability to control what type of technologies you use. So, either use a UNKNOWN-mode progress bar or split up the task of Statistics aggregation.

    How about splitting the computation on the database side, e.g. using stored procedures, so you have a granular way of reporting the current state of the computation job? E.g. using a temporary table to insert progress counters which are read by the thread updating the UIJob status. Then, you can even give the user feedback about what data is computet, e.g. “Computing statistics for January … Februrary … etc.”

    Another idea is to NOT use the database for the computation, only for data storage. I know a database can do it better than Java code, but why not extract the *business logic* into Java code. Then you have full control over what you display and where you hook in callbacks for progress feedback.

    An ugly but workable solution is to use an updater for the progress bar which uses data from previous job runs and a logarithmic progress curve. The user sees something progressing, but it is not 100% accurate. Still, it gives a much better feeling for endusers than just to see “nothing moving”.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s