Package jenkins.util

Class ProgressiveRendering

Direct Known Subclasses:

public abstract class ProgressiveRendering extends Object
A helper thread which does some computation in the background and displays incremental results using JavaScript. This is appropriate when the computation may be slow—too slow to do synchronously within the initial HTTP request—and has no side effects (since it may be canceled if the user simply browses to another page while it is running).
  1. Write a <script> section defining function display(data). (Call ts_refresh($('someid')) if using a sortable table.)
  2. Use <l:progressiveRendering handler="${it.something()}" callback="display"/> from your Jelly page to display a progress bar and initialize JavaScript infrastructure. (The callback attribute can take arbitrary JavaScript expression to be evaluated in the browser so long as it produces a function object.)
  3. Implement something() to create an instance of your subclass of ProgressiveRendering.
  4. Perform your work in compute().
  5. Periodically check canceled().
  6. As results become available, call progress(double).
  7. Make data() produce whatever JSON you want to send to the page to be displayed.
design-library demonstrates all this.
  • Constructor Summary

    Constructor for subclasses.
  • Method Summary

    Modifier and Type
    protected final boolean
    Checks whether the task has been canceled.
    protected abstract void
    Actually do the work.
    protected abstract net.sf.json.JSON
    Provide current data to the web page for display.
    protected ExecutorService
    May be overridden to provide an alternate executor service.
    final net.sf.json.JSONObject
    For internal use.
    protected final void
    progress(double completedFraction)
    Indicate what portion of the work has been done.
    final void
    For internal use.
    protected long
    May be overridden to control the inactivity timeout.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • ProgressiveRendering

      protected ProgressiveRendering()
      Constructor for subclasses.
  • Method Details

    • start

      @JavaScriptMethod public final void start()
      For internal use.
    • compute

      protected abstract void compute() throws Exception
      Actually do the work.

      The security context will be that in effect when the web request was made. Stapler.getCurrentRequest() will also be similar to that in effect when the web request was made; at least, Ancestors and basic request properties (URI, locale, and so on) will be available.

      Exception - whenever you like; the progress bar will indicate that an error occurred but details go to the log only
    • data

      @NonNull protected abstract net.sf.json.JSON data()
      Provide current data to the web page for display.

      While this could be an aggregate of everything that has been computed so far, more likely you want to supply only that data that is new since the last call (maybe just {} or []), so that the page can incrementally update bits of HTML rather than refreshing everything.

      You may want to make your implementation synchronized, so that it can track what was sent on a previous call, in which case any code running in compute() which modifies these fields should also temporarily be synchronized on the same monitor such as this.

      any JSON data you like
    • progress

      protected final void progress(double completedFraction)
      Indicate what portion of the work has been done. (Once compute() returns, the work is assumed to be complete regardless of this method.)
      completedFraction - estimated portion of work now done, from 0 (~ 0%) to 1 (~ 100%)
    • canceled

      protected final boolean canceled()
      Checks whether the task has been canceled. If the rendering page fails to send a heartbeat within a certain amount of time, the user is assumed to have moved on. Therefore compute() should periodically say: if (canceled()) return;
      true if user seems to have abandoned us, false if we should still run
    • news

      @JavaScriptMethod public final net.sf.json.JSONObject news()
      For internal use.
    • executorService

      protected ExecutorService executorService()
      May be overridden to provide an alternate executor service.
      by default, Timer.get()
    • timeout

      protected long timeout()
      May be overridden to control the inactivity timeout. If no request from the browser is received within this time, the next call to canceled() will be true.
      timeout in milliseconds; by default, 15000 (~ 15 seconds)