Concurrency and the workspace

We've already seen that workspace code must be aware of concurrency even if it is not using the concurrency framework. Batching of workspace changes and use of scheduling rules helps in sharing the workspace with other plug-ins (and their threads) that are modifying the workspace. Once your plug-in is using batching and rules (see Batching resource changes), it is easy to perform the same work using the platform concurrency mechanisms.

Workspace jobs

A Job is a basic unit of asynchronous work running concurrently with other jobs. The resources plug-in defines WorkspaceJob as a convenient mechanism for defining asynchronous resource modifications. Code that would normally be batched in an IWorkspaceRunnable is instead put in the runInWorkspace method of a workspace job subtype. Instead of running the code using IWorkspace protocol, the job is scheduled just like any other job. The appropriate scheduling rules must be added on the job before it is scheduled.

Let's look at an example workspace runnable and what we should do to make it a job:

IWorkspaceRunnable myRunnable = 
	new IWorkspaceRunnable() {
		public void run(IProgressMonitor monitor) throws CoreException {
			//do the actual work in here
			doSomeWork();
			...
		}
}

The work is moved to the appropriate method of our WorkspaceJob subtype.

class MyWorkspaceJob extends WorkspaceJob {
	public MyWorkspaceJob() {
		super("My Workspace Job");
	}
	public IStatus runInWorkspace(IProgressMonitor monitor) {
		//do the actual work in here
		doSomeWork();
		return Status.OK_STATUS;
	}
}

Our runnable had to be invoked specifically:

IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.run(myRunnable, myProject, IWorkspace.AVOID_UPDATE, null);

Our job is scheduled like any other job. The platform job manager will run it according to its priority, other jobs in the queue, and the scheduling rules. Note that we must attach the scheduling rule to the job in order to prevent simultaneous modification of myProject.

MyWorkspaceJob job = new MyWorkspaceJob();
job.setRule(myProject);
job.schedule();

Now that the operation has been structured as a job, all of the scheduling mechanisms (priority, delay, rescheduling) can be used. Resource change events will be batched until the job is finished running.