Skip to content

Commit 047d405

Browse files
cherry pick fix to Spurious Closed Pipes (ROBO-3083)
1 parent f1927a2 commit 047d405

4 files changed

Lines changed: 58 additions & 4 deletions

File tree

src/UiPath.CoreIpc.Tests/Implementation/SystemService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Globalization;
2+
using System.IO.Pipes;
23
using System.Reflection;
34
using System.Runtime.InteropServices;
45
using System.Text;

src/UiPath.CoreIpc/Connection.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
namespace UiPath.CoreIpc;
22
using static TaskCompletionPool<Response>;
33
using static IOHelpers;
4+
using System.IO.Pipes;
5+
using System.IO;
6+
using System.Threading;
7+
using Microsoft.Extensions.Logging;
8+
49
public sealed class Connection : IDisposable
510
{
611
private static readonly IOException ClosedException = new("Connection closed.");
@@ -183,14 +188,32 @@ private async ValueTask<bool> ReadBuffer(int length)
183188
{
184189
int offset = 0;
185190
int toRead = length;
191+
186192
do
187193
{
188-
var read = await Network.ReadAsync(
194+
int read;
195+
try
196+
{
197+
read = await Network.ReadAsync(
189198
#if NET461
190-
_buffer, offset, toRead);
199+
_buffer, offset, toRead);
191200
#else
192-
_buffer.AsMemory(offset, toRead));
201+
_buffer.AsMemory(offset, toRead));
193202
#endif
203+
}
204+
catch (OperationCanceledException ex) when (Network is PipeStream)
205+
{
206+
// Originally we decided to throw this exception the 2nd time we caught it, but later it was discovered that the NodeJS runtime continuosly retries.
207+
208+
// In some Windows client environments, OperationCanceledException is sporadically thrown on named pipe ReadAsync operation (ERROR_OPERATION_ABORTED on overlapped ReadFile)
209+
// The cause has not yet been discovered(os specific, antiviruses, monitoring application), and we have implemented a retry system
210+
// ROBO-3083
211+
212+
Logger.LogException(ex, $"Retrying ReadAsync for {Network.GetType()}");
213+
await Task.Delay(10); //Without this delay, on net framework can get OperationCanceledException on the second ReadAsync call
214+
continue;
215+
}
216+
194217
if (read == 0)
195218
{
196219
return false;
@@ -319,7 +342,7 @@ private void OnCancellationReceived(string requestId)
319342
{
320343
CancellationReceived(requestId);
321344
}
322-
catch(Exception ex)
345+
catch (Exception ex)
323346
{
324347
Log(ex);
325348
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#if NETFRAMEWORK
2+
3+
namespace System.Diagnostics.CodeAnalysis;
4+
5+
using static AttributeTargets;
6+
7+
[ExcludeFromCodeCoverage]
8+
[DebuggerNonUserCode]
9+
[AttributeUsage(Parameter | Property | ReturnValue, AllowMultiple = true)]
10+
internal sealed class NotNullIfNotNullAttribute : Attribute
11+
{
12+
/// <summary>
13+
/// Gets the associated parameter name.
14+
/// The output will be non-<see langword="null"/> if the argument to the
15+
/// parameter specified is non-<see langword="null"/>.
16+
/// </summary>
17+
public string ParameterName { get; }
18+
19+
/// <summary>
20+
/// Initializes the attribute with the associated parameter name.
21+
/// </summary>
22+
/// <param name="parameterName">
23+
/// The associated parameter name.
24+
/// The output will be non-<see langword="null"/> if the argument to the
25+
/// parameter specified is non-<see langword="null"/>.
26+
/// </param>
27+
public NotNullIfNotNullAttribute(string parameterName) =>
28+
ParameterName = parameterName;
29+
}
30+
#endif

0 commit comments

Comments
 (0)