This is an automated email from the ASF dual-hosted git repository. lkishalmi pushed a commit to branch release120 in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/release120 by this push: new f3ab92f [NETBEANS-4617] Flush Gradle Standard output in 200ms if it stalled f3ab92f is described below commit f3ab92f9c1397bda5a878aa0f62beefd2dc43198 Author: Laszlo Kishalmi <laszlo.kisha...@gmail.com> AuthorDate: Thu Jul 23 22:51:55 2020 -0700 [NETBEANS-4617] Flush Gradle Standard output in 200ms if it stalled --- .../execute/EscapeProcessingOutputStream.java | 56 ++++++--- .../modules/gradle/execute/EscapeProcessor.java | 2 +- .../gradle/execute/GradleColorEscapeProcessor.java | 134 --------------------- .../gradle/execute/GradlePlainEscapeProcessor.java | 5 +- .../execute/EscapeProcessingOutputStreamTest.java | 2 +- 5 files changed, 44 insertions(+), 155 deletions(-) diff --git a/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStream.java b/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStream.java index 6675c8c..b6deb58 100644 --- a/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStream.java +++ b/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStream.java @@ -23,7 +23,10 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import org.openide.util.RequestProcessor; /** * @@ -31,14 +34,23 @@ import java.util.concurrent.atomic.AtomicBoolean; */ class EscapeProcessingOutputStream extends OutputStream { + private static final RequestProcessor RP = new RequestProcessor(EscapeProcessingOutputStream.class); + boolean esc; boolean csi; final AtomicBoolean closed = new AtomicBoolean(); final ByteBuffer buffer = new ByteBuffer(); final EscapeProcessor processor; + private ScheduledFuture<?> autoFlush; + private final long autoFlushTimeout; public EscapeProcessingOutputStream(EscapeProcessor processor) { + this(processor, 200); + } + + public EscapeProcessingOutputStream(EscapeProcessor processor, long autoFlushTimeout) { this.processor = processor; + this.autoFlushTimeout = autoFlushTimeout; } @Override @@ -47,25 +59,31 @@ class EscapeProcessingOutputStream extends OutputStream { if (closed.get()) return; if (b == 0x1B) { esc = true; //Entering EscapeProcessingMode - processBulk(); //Process the Buffer collected so far + processBulk(false); //Process the Buffer collected so far } else if ((b == 0x5B) && esc) { csi = true; //Entering CSI mode we are going to esc = false; //read ANSI CSI commands from now on } else { esc = false; - if (csi) { - if ((b >= 0x40) && (b <= 0x7E)) { //Got a command byte - processCommand((char) b); //process that. - csi = false; + synchronized(buffer) { + if (csi) { + if ((b >= 0x40) && (b <= 0x7E)) { //Got a command byte + processCommand((char) b); //process that. + csi = false; + } else { + buffer.put(b); + } } else { - buffer.put(b); - } - } else { - if (b == '\n') { - buffer.put(b); - processBulk(); - } else if ((b >= 0x20) || (b == 0x09) || (b < 0)) { - buffer.put(b); + if (b == '\n') { + buffer.put(b); + processBulk(false); + } else if ((b >= 0x20) || (b == 0x09) || (b < 0)) { + buffer.put(b); + if (autoFlush != null) { + autoFlush.cancel(false); + } + autoFlush = RP.schedule(() -> processBulk(true), autoFlushTimeout, TimeUnit.MILLISECONDS); + } } } } @@ -81,7 +99,7 @@ class EscapeProcessingOutputStream extends OutputStream { @Override public void flush() throws IOException { if (!csi) { - processBulk(); + processBulk(false); } } @@ -101,10 +119,12 @@ class EscapeProcessingOutputStream extends OutputStream { processor.processCommand(sequence, command, args); } - private void processBulk() { - String out = buffer.read(); - if (out.length() > 0) { - processor.processText(out); + private void processBulk(boolean forced) { + synchronized (buffer) { + String out = buffer.read(); + if (out.length() > 0 || forced) { + processor.processText(out, forced); + } } } diff --git a/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessor.java b/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessor.java index 8f3f4b0..88ca120 100644 --- a/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessor.java +++ b/groovy/gradle/src/org/netbeans/modules/gradle/execute/EscapeProcessor.java @@ -36,5 +36,5 @@ public interface EscapeProcessor { * Text without ANSI control characters. * @param text */ - void processText(String text); + void processText(String text, boolean forceOutput); } diff --git a/groovy/gradle/src/org/netbeans/modules/gradle/execute/GradleColorEscapeProcessor.java b/groovy/gradle/src/org/netbeans/modules/gradle/execute/GradleColorEscapeProcessor.java deleted file mode 100644 index 5bc7ee0..0000000 --- a/groovy/gradle/src/org/netbeans/modules/gradle/execute/GradleColorEscapeProcessor.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.netbeans.modules.gradle.execute; - -import org.netbeans.modules.gradle.api.execute.RunConfig; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.netbeans.api.progress.ProgressHandle; -import static org.openide.windows.IOColors.OutputType.*; -import org.openide.windows.InputOutput; - -/** - * - * @author Laszlo Kishalmi - */ -public class GradleColorEscapeProcessor extends GradlePlainEscapeProcessor { - - private static final Pattern PROGRESS_PATTERN = Pattern.compile("> Building (\\d+)%(.*)"); - - final ProgressHandle handle; - - StringBuilder statusLine = new StringBuilder(120); - boolean append = true; - boolean hasProgress; - - public GradleColorEscapeProcessor(InputOutput io, ProgressHandle handle, RunConfig cfg) { - super(io, cfg, false); - this.handle = handle; - } - - @Override - public void processCommand(String sequence, char command, int... a) { - if (a.length > 0) { - int param = a[0]; - switch (command) { - case 'm': - switch (param) { - case 1: - outType = LOG_DEBUG; - break; - case 22: - outType = OUTPUT; - break; - case 31: - outType = LOG_FAILURE; - break; - case 33: - outType = LOG_WARNING; - break; - case 39: - outType = OUTPUT; - break; - } - break; - case 'D': - if (statusLine != null) { - statusLine.delete(statusLine.length() - param, statusLine.length()); - } - break; - case 'A': - append = true; - break; - default: - break; - } - } - } - - @Override - public void processText(String text) { - if (outType == LOG_DEBUG) { - if (!text.startsWith("--")) { - statusLine.append(text); - processProgress(); - } else { - outType = OUTPUT; - } - } - if (outType != LOG_DEBUG) { - String out = text; - if (!append) { - io.getOut().println(); - } - append = !text.endsWith("\n"); - if (!append) { - out = text.substring(0, text.length() - 1); - } - - super.processText(out); - } - } - - private void processProgress() { - Matcher matcher = PROGRESS_PATTERN.matcher(statusLine); - if (matcher.matches()) { - if (!hasProgress) { - handle.switchToDeterminate(100); - hasProgress = true; - } - String percent = matcher.group(1); - String status = matcher.group(2); - try { - handle.progress(status, Integer.parseInt(percent)); - } catch (NumberFormatException ex) { - //Unlikely to happen. - } - } else { - handle.progress(statusLine.toString()); - } - } - -} diff --git a/groovy/gradle/src/org/netbeans/modules/gradle/execute/GradlePlainEscapeProcessor.java b/groovy/gradle/src/org/netbeans/modules/gradle/execute/GradlePlainEscapeProcessor.java index d63b330..5d1acce 100644 --- a/groovy/gradle/src/org/netbeans/modules/gradle/execute/GradlePlainEscapeProcessor.java +++ b/groovy/gradle/src/org/netbeans/modules/gradle/execute/GradlePlainEscapeProcessor.java @@ -79,7 +79,7 @@ public class GradlePlainEscapeProcessor implements EscapeProcessor { } @Override - public void processText(String text) { + public void processText(String text, boolean forceOutput) { line.append(text); boolean eol = text.endsWith("\n"); if (eol) { @@ -98,6 +98,9 @@ public class GradlePlainEscapeProcessor implements EscapeProcessor { } output.print("\n"); line.setLength(0); + } else if (forceOutput && line.length() > 0) { + output.print(line.toString()); + line.setLength(0); } } diff --git a/groovy/gradle/test/unit/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStreamTest.java b/groovy/gradle/test/unit/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStreamTest.java index 29d1606..66ef6fd 100644 --- a/groovy/gradle/test/unit/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStreamTest.java +++ b/groovy/gradle/test/unit/src/org/netbeans/modules/gradle/execute/EscapeProcessingOutputStreamTest.java @@ -42,7 +42,7 @@ public class EscapeProcessingOutputStreamTest { } @Override - public void processText(String text) { + public void processText(String text, boolean forced) { output.append(text); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists