Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[buckminster-dev] WorkspaceCatchUpJob blocks UI

Hi,

I'm having fairly complex workspaces (comparable in size to the buckminster project) and what always annoyed me is that Buckminster -> invoke action freezes the UI for about 30 seconds on first usage. Since I already provided a new invoke action dialog that is perfectly suited for long running background operations with proper progress information, I decided to write a patch so this dialog won't freeze the UI anymore. While this is no problem to do (I can offer a patch this weekend if you're interested), I had to notice some rather odd things about the current implementation. I'd like to ask about these code pieces, since I think fixing the dialog will solve my problem at hand, but does not fix the root of the problem.

Ok, so what happens? The AbstractCSpecAction tries to retrieve a CSpec for the current selection in selectionChanged:
m_selectedComponent = (CSpec)((IAdaptable)first).getAdapter(CSpec.class);

This will end up in WorkspaceInfo in these two methods:

private static void checkFirstUse()
	{
		// We want the first caller to star the job. That job in turn will
		// result in recursive calls that should return immediately.
		//
		synchronized(WorkspaceInfo.class)
		{
			if(s_hasBeenActivated)
				return;
			s_hasBeenActivated = true;
		}
		runWorkspaceCatchUpJob();
	}

	public static void runWorkspaceCatchUpJob()
	{
		WorkspaceCatchUpJob catchUpJob = new WorkspaceCatchUpJob();
		catchUpJob.schedule();
		try
		{
			catchUpJob.join();
		}
		catch(InterruptedException e)
		{
		}
	}

As you can see, the first caller will trigger the job and will join the job. In other words, the call for the CSpec Adapter will not return until the WorkspaceCatchUpJob is completed and this is what freezes the UI. However, as you can see, only the first caller joins the job, if another thread calls methods in WorkspaceInfo while the job is still running, these calls wil return immediatly. Why is that so and is that really the intention?
To verify this, I changed the AbstractCSpecAction#selectionChanged a little:
		if(first instanceof IAdaptable)
		{
			new Thread(new Runnable()
			{

				public void run()
				{
					((IAdaptable)first).getAdapter(CSpec.class);
					System.out.println("done in background thread");

				}
			}).start();
			try
			{
				Thread.sleep(1000);
			}
			catch(InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			m_selectedComponent = (CSpec)((IAdaptable)first).getAdapter(CSpec.class);
			System.out.println("done in UI thread");
		}

So a background thread first tries to fetch the CSpec and then the UI thread tries the same. The result is (for non-trivial workspaces) always:
done in UI thread
done in background thread (a lot later)

Surprisingly enough this shows the InvokeActionDialog correctly and significantly faster, even though the WorkspaceCatchUpJob did not complete. So the next question: are there scenarios where the job has to be completed before all attributes of the choosen CSpec become available, or would it actually work without waiting for completion of the job?

If such scenarios exist, should I just fix the Dialog + AbstractCSpecAction in a way that the blocking call does not happen in the UI thread and the dialog can properly display progress, or should I also fix that every call to WorkspaceInfo will be blocking until the job is completed?

Best regards,
Johannes


Back to the top