Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "E4/EAS/Progress Service"

< E4‎ | EAS
(Eclipse 3.x API)
(e4 (Java))
Line 77: Line 77:
 
</source>
 
</source>
  
The runnable context defines how progress is reported and whether status is visible, etc.  Example contexts include:
+
The runnable context defines  
 +
* how something is run.
 +
** Synchronous (in current thread)
 +
** Modal (forked but blocking on result)
 +
** Asynchronously (in the background)
 +
* How progress is reported
 +
* How status is reported
 +
* Locks and scheduling rules (ISchedulingRule)
 +
* Batching of operations/notifications (IWorkspaceOperation)
 +
Example contexts include:
 
* wizard or dialog modal context (local progress and error reporting)
 
* wizard or dialog modal context (local progress and error reporting)
 
* parts (adornment when busy or local progress, centralized error reporting via dialog?)
 
* parts (adornment when busy or local progress, centralized error reporting via dialog?)
 +
* operations on a shared set of resources
 
* jobs (not tied to any visible part, centralized error and progress reporting)
 
* jobs (not tied to any visible part, centralized error and progress reporting)
* futures (same as above?)
+
* futures (same as above with post-processing)
  
  
The main idea here is that how the code is organized (the runnable) is separate from how progress and errors are reported, and you shouldn't have to know in advance when writing the code whether you'll be run synch or asynch, whether status will be shown or logged, how progress is reported.
+
The main idea here is that how the code is organized (the runnable) is separate from how progress and errors are reported, and you shouldn't have to know in advance when writing the code how your code will be run or where things get reported.
 +
 
 +
'''Questions:'''
 +
* Is there really a runnable context (implemented by various UI elements such as parts, wizards, etc.)  Who is told to run the runnable and how
 +
* Is a localized status and progress reporting service inferred by a particular kind of runnable context or is it injected, or is it obtained from the IEclipseContext?
 +
 
  
 
Need to review the AC's [[Architecture Council/Minutes May 15 2008#Becoming More Asynchronous|meeting]] [[Architecture Council/Minutes May 15 2008#Jobs and Scheduling_Rules|minutes]] prior to the creation of this e4 API.
 
Need to review the AC's [[Architecture Council/Minutes May 15 2008#Becoming More Asynchronous|meeting]] [[Architecture Council/Minutes May 15 2008#Jobs and Scheduling_Rules|minutes]] prior to the creation of this e4 API.

Revision as of 16:48, 29 October 2009

Based on a user's interaction with an application, the application may wish to schedule work to be done by other worker threads. The work that is done on these other worker threads may or may not be presented to the user. If background work is being invoked automatically based on some conditions, it may not necessarily be useful to present this information to the user. However, if the user explicitly invokes an action that causes a long-running operation to begin, they may wish to know about this so that they can respond accordingly when the operation has completed or just cancel the operation outright.

Eclipse 3.x API

In Eclipse 3.x, there are a variety of classes and interfaces that exposes progress reporting and work scheduling features.

  • org.eclipse.jface.operation.IRunnableContext
  • org.eclipse.ui.progress.IProgressService
  • org.eclipse.ui.progress.IWorkbenchSiteProgressService
  • org.eclipse.jface.operation.IRunnableWithProgress
  • org.eclipse.core.runtime.jobs.Job

Typically, for scheduling work to be completed by a worker thread, the Jobs framework is used.

Job aJob = new Job("My long-running operation...") {
  protected IStatus run(IProgressMonitor monitor) {
    // do stuff and report progress via the IPM
    return Status.OK_STATUS;
  }
};
// true to indicate that this job was initiated by a UI end user
aJob.setUser(true);

In the IProgressService and IWorkbenchSiteProgressService case, these are queried from the local service locator.

Critique:

  • As shown above, you need to know how your code is going to be used (in a worker thread) at the time you create it (I need a Job).
  • We have no headless IRunnableWithProgress. (Today we have JFace IRunnableWithProgress, Job.run(IProgressMonitor), IDE's WorkspaceModifyOperation, Equinox future's IProgressRunnable). If we had a core-level IRunnableWithProgress then applications could define runnables that could be run in different execution contexts (UI modal context, user job, future, etc.) Today the application has to define its own operations framework to handle these differences.
  • Likewise, we need a headless progress service (generalization of IWorkbenchSiteProgressService) so that jobs/runnables can be run in these different execution contexts with different style progress reporting depending on where they are run. See Bug 293098.
  • Examples of 3.x limitations
    • If you a run a job in a modal dialog, there is no jobs progress dialog and your only progress indicator is the status bar unless you happen to have the progress view open.
    • Some constructs (DeferredTreeContentManager) use jobs and only know about certain progress contexts. If I run a deferred fetch in a site, the site is adorned and the job progress is reported normally. If I run the same viewer in a dialog, there is no local progress.
    • If you run some operation synchronously and want to report failure, you have to decide in-line whether its logged, shown, or both, but that decision is not necessarily appropriate on the calling side.
    • If you want to show progress in multiple places, you have to wrap the monitor. If you are using jobs this means defining your own framework so you can intercept the monitor on the run method and wrap it.

e4 (Java)

It would be nice to create a generic runnable (with progress. is it injected?)

IRunnable runnable = new Runnable("My long-running operation...") {
  protected IStatus run(IProgressMonitor monitor) {
    IStatus status = Status.OK_STATUS;
    monitor.beginTask("foo", 100);
    try {
       doFirstHalfFoo();
       monitor.worked(50);
       doSecondHalfFoo();
    } catch (FooException e) {
       status = new Status(IStatus.ERROR, "id", "foo failure message", e);
    } finally {
       monitor.done();
    }
    return status;
  }
};

Another alternative is that status and progress are both injected, so that there is no return status from the runnable itself. There is likely some relationship between the runnable context and how/where status is reported. Not sure who knows about who.

@Inject Provider<StatusHandler> statusHandler;
@Inject Provider<RunnableContext> runnableContext;
IRunnable runnable = new Runnable("My long-running operation...") {
  protected IStatus run() {
    IProgressMonitor monitor = runnableContext.get().getProgressMonitor();
    monitor.beginTask("foo", 100);
    try {
       doFirstHalfFoo();
       monitor.worked(50);
       doSecondHalfFoo();
    } catch (FooException e) {
       statusHandler.get().handle(e, "foo failure message", runnableContext.get().howAndWhereDoIShowErrors()); 
    } finally {
       monitor.done();
    }
  }
};

The runnable context defines

  • how something is run.
    • Synchronous (in current thread)
    • Modal (forked but blocking on result)
    • Asynchronously (in the background)
  • How progress is reported
  • How status is reported
  • Locks and scheduling rules (ISchedulingRule)
  • Batching of operations/notifications (IWorkspaceOperation)

Example contexts include:

  • wizard or dialog modal context (local progress and error reporting)
  • parts (adornment when busy or local progress, centralized error reporting via dialog?)
  • operations on a shared set of resources
  • jobs (not tied to any visible part, centralized error and progress reporting)
  • futures (same as above with post-processing)


The main idea here is that how the code is organized (the runnable) is separate from how progress and errors are reported, and you shouldn't have to know in advance when writing the code how your code will be run or where things get reported.

Questions:

  • Is there really a runnable context (implemented by various UI elements such as parts, wizards, etc.) Who is told to run the runnable and how?
  • Is a localized status and progress reporting service inferred by a particular kind of runnable context or is it injected, or is it obtained from the IEclipseContext?


Need to review the AC's meeting minutes prior to the creation of this e4 API.

Back to the top