Skip to content

Commit

Permalink
Python: Fix robot hang when net runtime not installed (24.12) [STUD-7…
Browse files Browse the repository at this point in the history
…1044]

Use Connect with timeout when connecting pipes
Throw exception when the host process has exit
  • Loading branch information
viogroza committed Nov 22, 2024
1 parent 8f4b12d commit 8f2be1e
Showing 1 changed file with 52 additions and 7 deletions.
59 changes: 52 additions & 7 deletions Activities/Shared/UiPath.Shared.Service/Client/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ internal class Controller<T>
/// </summary>
private readonly TimeSpan RetryInterval = TimeSpan.FromMilliseconds(50);

//Timeout in milliseconds for pipe connection (attempt)
private readonly int PipeConnectionTimeoutMs = 1000;

internal int ProcessId { get; private set; }

internal string Arguments { get; set; } = null;
Expand Down Expand Up @@ -59,7 +62,7 @@ private NamedPipeClientStream StartHostService()
else
{
folder = Path.GetDirectoryName(Assembly.GetAssembly(typeof(T)).Location).Replace("/lib/", "/bin/");
Arguments = string.Concat(Path.Combine(folder, ExeFile.Replace(".exe",".dll")), " ", Arguments);
Arguments = string.Concat(Path.Combine(folder, ExeFile.Replace(".exe", ".dll")), " ", Arguments);
exeFullPath = "dotnet";
}

Expand All @@ -73,28 +76,70 @@ private NamedPipeClientStream StartHostService()
// start the host process
ProcessStartInfo psi = new ProcessStartInfo()
{
UseShellExecute = true,
UseShellExecute = false,
FileName = exeFullPath,
WorkingDirectory = folder,
Arguments = Arguments,
WindowStyle = Visible ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden
WindowStyle = Visible ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden,
RedirectStandardError = true,
RedirectStandardOutput = true
};
Process process = Process.Start(psi);

// wait for service to become available
bool ServiceReady()
{
pipeClient =
new NamedPipeClientStream(".", process.Id.ToString(), PipeDirection.InOut,
PipeOptions.Asynchronous);
if (HostProcessHasExited())
{
using (var readerOutput = process.StandardOutput)
using (var readerError = process.StandardError)
{
string output = readerOutput.ReadToEnd();
string error = readerError.ReadToEnd();
throw new Exception($"Host process has exit!\n output: {output} \n error: {error} \n");
}
}

if (pipeClient == null)
{
pipeClient = new NamedPipeClientStream(".", process.Id.ToString(), PipeDirection.InOut, PipeOptions.Asynchronous);
}

pipeClient.Connect();
TryConnectPipeClient();
if (pipeClient.IsConnected)
{
return true;
}
return false;
}

void TryConnectPipeClient()
{
try
{
pipeClient.Connect(PipeConnectionTimeoutMs);
}
catch
{
//In case of exception we are going to retry to connect next time
//On timeout, if failure persists exception will be thrown
}
}

bool HostProcessHasExited()
{
try
{
return process.HasExited;
}
catch
{
//For wathever reason if HasExited throws, we assume that the process has not exited
//Error will be thrown when timeout expires
return false;
}
}

Retry(ServiceReady, StartTimeout, RetryInterval);
return pipeClient;
}
Expand Down

0 comments on commit 8f2be1e

Please sign in to comment.