Skip to content

Commit

Permalink
Merge pull request #342 from costleya/fix-epipe-error
Browse files Browse the repository at this point in the history
fix(jsii-dotnet-runtime): Fix EPIPE on Windows.
  • Loading branch information
costleya authored Jan 10, 2019
2 parents 311bf88 + 4d8a659 commit 0301e30
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 15 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules/
.BUILD_COMPLETED
lerna-debug.log
.DS_Store
.idea
.idea
/dist
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ public void NullShouldBeTreatedAsUndefined()
obj.ChangeMeToUndefined = null;
obj.VerifyPropertyIsUndefined();
}

[Fact(DisplayName = Prefix + nameof(JsiiAgent))]
public void JsiiAgent()
{
Expand Down
1 change: 1 addition & 0 deletions packages/jsii-dotnet-runtime/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ coverage/
bin/
cli/
obj/
*.DotSettings.user
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.IO;
using Amazon.JSII.Runtime.Services;
using NSubstitute;
using NSubstitute.ReturnsExtensions;
using Xunit;

namespace Amazon.JSII.Runtime.UnitTests.Client
{
public class RuntimeTests
{
private const string Prefix = "Runtime.";

private INodeProcess _nodeProcessMock;
private TextReader _standardOutputMock;
private TextReader _standardErrorMock;

private IRuntime _sut;

public RuntimeTests()
{
_nodeProcessMock = Substitute.For<INodeProcess>();
_standardOutputMock = Substitute.For<TextReader>();
_standardErrorMock = Substitute.For<TextReader>();

_nodeProcessMock.StandardOutput.Returns(_standardOutputMock);
_nodeProcessMock.StandardError.Returns(_standardErrorMock);

_sut = new Services.Runtime(_nodeProcessMock);
}

[Fact(DisplayName = Prefix + nameof(ThrowsJsiiExceptionWhenResponseNotReceived))]
public void ThrowsJsiiExceptionWhenResponseNotReceived()
{
_nodeProcessMock.StandardOutput.ReadLine().ReturnsNull();
_nodeProcessMock.StandardError.ReadToEnd().Returns("This is a test.");

var ex = Assert.Throws<JsiiException>(() => _sut.ReadResponse());
Assert.Equal("Child process exited unexpectedly: This is a test.", ex.Message);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using Amazon.JSII.JsonModel.Api.Response;
using System;
using System;
using Amazon.JSII.JsonModel.Api.Response;

namespace Amazon.JSII.Runtime
{
public class JsiiException : Exception
{
public ErrorResponse ErrorResponse { get; }

public JsiiException(string message) : base(message)
{
}

public JsiiException(string message, Exception innerException)
: base(message, innerException)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ namespace Amazon.JSII.Runtime.Services
{
public interface INodeProcess : IDisposable
{
StreamWriter StandardInput { get; }
TextWriter StandardInput { get; }

StreamReader StandardOutput { get; }
TextReader StandardOutput { get; }

TextReader StandardError { get; }
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.Extensions.Logging;
using System;
using System;
using System.Diagnostics;
using System.IO;
using Microsoft.Extensions.Logging;

namespace Amazon.JSII.Runtime.Services
{
Expand All @@ -23,24 +23,30 @@ public NodeProcess(IJsiiRuntimeProvider jsiiRuntimeProvider, ILoggerFactory logg
Arguments = "--max-old-space-size=4096 " + jsiiRuntimeProvider.JsiiRuntimePath,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};

_process.StartInfo.EnvironmentVariables.Add("JSII_AGENT", "DotNet/" + Environment.Version.ToString());
_process.StartInfo.EnvironmentVariables.Add("JSII_AGENT", "DotNet/" + Environment.Version);

_logger.LogDebug("Starting jsii runtime...");
_logger.LogDebug($"{_process.StartInfo.FileName} {_process.StartInfo.Arguments}");

_process.Start();
}

public StreamWriter StandardInput => _process.StandardInput;
public TextWriter StandardInput => _process.StandardInput;

public StreamReader StandardOutput => _process.StandardOutput;
public TextReader StandardOutput => _process.StandardOutput;

public TextReader StandardError => _process.StandardError;

void IDisposable.Dispose()
{
StandardInput.Dispose();
StandardOutput.Dispose();
StandardError.Dispose();
_process.Dispose();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;

namespace Amazon.JSII.Runtime.Services
{
Expand All @@ -9,11 +10,22 @@ public class Runtime : IRuntime
public Runtime(INodeProcess nodeProcess)
{
_nodeProcess = nodeProcess ?? throw new ArgumentNullException(nameof(nodeProcess));
if (Environment.GetEnvironmentVariable("JSII_DEBUG") != null)
{
Task.Run(() => RedirectStandardError());
}
}

public string ReadResponse()
{
return _nodeProcess.StandardOutput.ReadLine();
var response = _nodeProcess.StandardOutput.ReadLine();
if (string.IsNullOrEmpty(response))
{
var errorMessage = _nodeProcess.StandardError.ReadToEnd();
throw new JsiiException("Child process exited unexpectedly: " + errorMessage);
}

return response;
}

public void WriteRequest(string request)
Expand All @@ -31,5 +43,13 @@ public void WriteRequest(string request)
_nodeProcess.StandardInput.WriteLine(request);
_nodeProcess.StandardInput.Flush();
}

private void RedirectStandardError()
{
while (true)
{
Console.Error.WriteLine(_nodeProcess.StandardError.ReadLine());
}
}
}
}

0 comments on commit 0301e30

Please sign in to comment.