[
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