changeset 1011:17bd4181c476

TW-55105 Add "teamcity.hg.command.readBytesLimit" to avoid OutOfMemoryError on input reading
author Nikolai.Kulakov@UNIT-1322.Labs.IntelliJ.Net
date Thu, 31 Jan 2019 19:14:24 +0300
parents b05a042511da
children 6b69c7a12f76
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java
diffstat 2 files changed, 30 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java	Fri Oct 19 15:42:44 2018 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandSettings.java	Thu Jan 31 19:14:24 2019 +0300
@@ -29,6 +29,7 @@
  */
 public class CommandSettings {
 
+  private final int myReadBytesLimit = TeamCityProperties.getInteger("teamcity.hg.command.readBytesLimit", Integer.MAX_VALUE);
   private int myTimeout = TeamCityProperties.getInteger("teamcity.hg.command.defaultExecutionTimeout", 3600);
   private final Set<String> myPrivateData = new HashSet<String>();
   private boolean myCheckForFailure = true;
@@ -41,6 +42,10 @@
   private boolean myUseCommandlineViaFileWrapper = false;
   private MercurialProgress myProgress = MercurialProgress.NO_OP;
 
+  public int getReadBytesLimit() {
+    return myReadBytesLimit;
+  }
+
   public final int getMaxCommandLineSize() {
     return myUseCommandlineViaFileWrapper ? Integer.MAX_VALUE : OS.getMaxCommandLineSize();
   }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java	Fri Oct 19 15:42:44 2018 +0200
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java	Thu Jan 31 19:14:24 2019 +0300
@@ -104,7 +104,7 @@
   }
 
   private static CommandResult runCommandWithName(MercurialCommandLine cli, CommandSettings settings, String command) throws VcsException {
-    CommandResult res = run(cli, settings.getTimeout(), command, settings.getPrivateData(), settings);
+    CommandResult res = run(cli, settings.getTimeout(), settings.getReadBytesLimit(), command, settings.getPrivateData(), settings);
     if (settings.isCheckForFailure() || settings.isFailWithNonEmptyStderr())
       res.checkFailure(settings.isFailWithNonEmptyStderr());
     logCommandOutput(command, res, settings);
@@ -114,6 +114,7 @@
   @NotNull
   private static CommandResult run(@NotNull final MercurialCommandLine cli,
                                    final int executionTimeout,
+                                   final int readBytesLimit,
                                    @NotNull final String command,
                                    @NotNull final Set<String> privateData,
                                    @NotNull CommandSettings settings) {
@@ -127,18 +128,30 @@
     } else {
       stderrBuffer = new ByteArrayOutputStream();
     }
-    ExecResult res = SimpleCommandLineProcessRunner.runCommandSecure(cli.toGeneralCommandLine(), command, null, new SimpleCommandLineProcessRunner.ProcessRunCallbackAdapter() {
-      @Override
-      public Integer getOutputIdleSecondsTimeout() {
-        return executionTimeout;
-      }
+    ExecResult res = SimpleCommandLineProcessRunner.runCommandSecure(
+            cli.toGeneralCommandLine(), command, null,
+            new SimpleCommandLineProcessRunner.ProcessRunCallback() {
+              @Override
+              public void onProcessStarted(@NotNull Process ps) {
+              }
 
-      @Override
-      public void onProcessFinished(@NotNull Process ps) {
-        long duration = System.currentTimeMillis() - start;
-        Loggers.VCS.debug("Command " + command + " took " + duration + "ms");
-      }
-    }, stdoutBuffer, stderrBuffer);
+              @Override
+              public void onProcessFinished(@NotNull Process ps) {
+                long duration = System.currentTimeMillis() - start;
+                Loggers.VCS.debug("Command " + command + " took " + duration + "ms");
+              }
+
+              @Override
+              public Integer getOutputIdleSecondsTimeout() {
+                return executionTimeout;
+              }
+
+              @Override
+              public Integer getMaxAcceptedOutputSize() {
+                return readBytesLimit;
+              }
+            },
+            stdoutBuffer, stderrBuffer);
     return new CommandResult(Loggers.VCS, command, res, privateData, settings, cli.getWorkingDirectory());
   }