diff --git a/core/src/main/java/jenkins/util/ProgressiveRendering.java b/core/src/main/java/jenkins/util/ProgressiveRendering.java new file mode 100644 index 0000000000000000000000000000000000000000..da80c8af6b0ab6c0b74ab347a59955e3672d7a39 --- /dev/null +++ b/core/src/main/java/jenkins/util/ProgressiveRendering.java @@ -0,0 +1,194 @@ +/* + * The MIT License + * + * Copyright 2012 Jesse Glick. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.util; + +import edu.umd.cs.findbugs.annotations.SuppressWarnings; +import hudson.model.Computer; +import java.util.concurrent.ExecutorService; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.Nonnull; +import net.sf.json.JSON; +import net.sf.json.JSONObject; +import org.acegisecurity.context.SecurityContext; +import org.acegisecurity.context.SecurityContextHolder; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.bind.JavaScriptMethod; + +/** + * 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 {@code + diff --git a/core/src/main/resources/lib/layout/progressiveRendering/progressiveRendering.js b/core/src/main/resources/lib/layout/progressiveRendering/progressiveRendering.js new file mode 100644 index 0000000000000000000000000000000000000000..d737a946fe060e111eb5d6e567566ce43de4bbdb --- /dev/null +++ b/core/src/main/resources/lib/layout/progressiveRendering/progressiveRendering.js @@ -0,0 +1,49 @@ +/* + * The MIT License + * + * Copyright 2012 Jesse Glick. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +function progressivelyRender(handler, callback) { + function checkNews(response) { + var r = response.responseObject(); + if (r.status == 'done') { + // XXX why does window[callback] not work? + eval(callback)(r.data); + $('status').style.display = 'none'; + } else if (r.status == 'canceled') { + // XXX ugly; replace with single tr of class=unknown? + $$('#status .progress-bar-done')[0].innerHTML = 'Aborted.'; + } else if (r.status == 'error') { + $$('#status .progress-bar-done')[0].style.width = '100%'; + $$('#status .progress-bar-left')[0].style.width = '0%'; + $('status').class = 'progress-bar red'; // XXX does not seem to work + } else { + eval(callback)(r.data); + $$('#status .progress-bar-done')[0].style.width = (100 * r.status) + '%'; + $$('#status .progress-bar-left')[0].style.width = (100 - 100 * r.status) + '%'; + setTimeout(function() { + handler.news(checkNews); + }, 500); + } + } + handler.news(checkNews); +} diff --git a/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/ProgressivelyRendered.java b/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/ProgressivelyRendered.java new file mode 100644 index 0000000000000000000000000000000000000000..e70729e5beb519be4509c65c09f1f87767a3c502 --- /dev/null +++ b/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/ProgressivelyRendered.java @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright 2012 Jesse Glick. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.plugins.ui_samples; + +import hudson.Extension; +import java.util.LinkedList; +import java.util.List; +import jenkins.util.ProgressiveRendering; +import net.sf.json.JSON; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; + +@Extension +public class ProgressivelyRendered extends UISample { + + @Override public String getDescription() { + return "Shows how to use progressively rendered content to avoid overloading the server with a slow HTTP request."; + } + + public ProgressiveRendering factor(final String numberS) { + return new ProgressiveRendering() { + final List newFactors = new LinkedList(); + @Override protected void compute() throws Exception { + int number = Integer.parseInt(numberS); // try entering a nonnumeric value! + // Deliberately inefficient: + for (int i = 1; i <= number; i++) { + if (canceled()) { + return; + } + if (i % 1000000 == 0) { + Thread.sleep(10); // take a breather + } + if (number % i == 0) { + synchronized (this) { + newFactors.add(i); + } + } + progress(((double) i) / number); + } + } + @Override protected synchronized JSON data() { + JSONArray r = new JSONArray(); + for (int i : newFactors) { + r.add(i); + } + newFactors.clear(); + return new JSONObject().accumulate("newfactors", r); + } + }; + } + + @Extension + public static final class DescriptorImpl extends UISampleDescriptor {} + +} diff --git a/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/ProgressivelyRendered/index.jelly b/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/ProgressivelyRendered/index.jelly new file mode 100644 index 0000000000000000000000000000000000000000..b8a949b2848268accb94db326ea91fa60323f1d2 --- /dev/null +++ b/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/ProgressivelyRendered/index.jelly @@ -0,0 +1,50 @@ + + + + +

    + Shows how to do something slow on the server while displaying progress. +

    + +
    + Enter a big number: +
    + + +

    Factors of ${number}:

    + +
      + + + +