Skip to content

Commit ebf5a18

Browse files
Eliminate the NodeHostingModel enum because it isn't extensible. Instead, use extension methods on NodeServicesOptions to configure a NodeInstanceFactory.
1 parent d865e1f commit ebf5a18

File tree

8 files changed

+54
-81
lines changed

8 files changed

+54
-81
lines changed

samples/misc/LatencyTest/Program.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public static void Main(string[] args) {
1616
// Set up the DI system
1717
var services = new ServiceCollection();
1818
services.AddNodeServices(options => {
19-
options.HostingModel = NodeServicesOptions.DefaultNodeHostingModel;
2019
options.ProjectPath = Directory.GetCurrentDirectory();
2120
options.WatchFileExtensions = new string[] {}; // Don't watch anything
2221
});

src/Microsoft.AspNetCore.NodeServices/Configuration/NodeHostingModel.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using Microsoft.AspNetCore.NodeServices.HostingModels;
32

43
namespace Microsoft.AspNetCore.NodeServices
54
{
@@ -19,33 +18,8 @@ public static INodeServices CreateNodeServices(NodeServicesOptions options)
1918
{
2019
throw new ArgumentNullException(nameof (options));
2120
}
22-
23-
return new NodeServicesImpl(() => CreateNodeInstance(options));
24-
}
2521

26-
private static INodeInstance CreateNodeInstance(NodeServicesOptions options)
27-
{
28-
if (options.NodeInstanceFactory != null)
29-
{
30-
// If you've explicitly supplied an INodeInstance factory, we'll use that. This is useful for
31-
// custom INodeInstance implementations.
32-
return options.NodeInstanceFactory();
33-
}
34-
else
35-
{
36-
switch (options.HostingModel)
37-
{
38-
case NodeHostingModel.Http:
39-
return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, options.NodeInstanceOutputLogger,
40-
options.EnvironmentVariables, options.InvocationTimeoutMilliseconds, options.LaunchWithDebugging, options.DebuggingPort, /* port */ 0);
41-
case NodeHostingModel.Socket:
42-
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
43-
return new SocketNodeInstance(options.ProjectPath, options.WatchFileExtensions, pipeName, options.NodeInstanceOutputLogger,
44-
options.EnvironmentVariables, options.InvocationTimeoutMilliseconds, options.LaunchWithDebugging, options.DebuggingPort);
45-
default:
46-
throw new ArgumentException("Unknown hosting model: " + options.HostingModel);
47-
}
48-
}
22+
return new NodeServicesImpl(options.NodeInstanceFactory);
4923
}
5024
}
5125
}

src/Microsoft.AspNetCore.NodeServices/Configuration/NodeServicesOptions.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ namespace Microsoft.AspNetCore.NodeServices
1313
/// </summary>
1414
public class NodeServicesOptions
1515
{
16-
/// <summary>
17-
/// Defines the default <see cref="NodeHostingModel"/>.
18-
/// </summary>
19-
public const NodeHostingModel DefaultNodeHostingModel = NodeHostingModel.Http;
20-
2116
internal const string TimeoutConfigPropertyName = nameof(InvocationTimeoutMilliseconds);
2217
private const int DefaultInvocationTimeoutMilliseconds = 60 * 1000;
2318
private const string LogCategoryName = "Microsoft.AspNetCore.NodeServices";
@@ -36,7 +31,6 @@ public NodeServicesOptions(IServiceProvider serviceProvider)
3631

3732
EnvironmentVariables = new Dictionary<string, string>();
3833
InvocationTimeoutMilliseconds = DefaultInvocationTimeoutMilliseconds;
39-
HostingModel = DefaultNodeHostingModel;
4034
WatchFileExtensions = (string[])DefaultWatchFileExtensions.Clone();
4135

4236
// In an ASP.NET environment, we can use the IHostingEnvironment data to auto-populate a few
@@ -53,15 +47,15 @@ public NodeServicesOptions(IServiceProvider serviceProvider)
5347
NodeInstanceOutputLogger = loggerFactory != null
5448
? loggerFactory.CreateLogger(LogCategoryName)
5549
: new ConsoleLogger(LogCategoryName, null, false);
56-
}
5750

58-
/// <summary>
59-
/// Specifies which <see cref="NodeHostingModel"/> should be used.
60-
/// </summary>
61-
public NodeHostingModel HostingModel { get; set; }
51+
// By default, we use this package's built-in out-of-process-via-HTTP hosting/transport
52+
this.UseHttpHosting();
53+
}
6254

6355
/// <summary>
64-
/// If set, this callback function will be invoked to supply the <see cref="INodeServices"/> instance.
56+
/// Specifies how to construct Node.js instances. An <see cref="INodeInstance"/> encapsulates all details about
57+
/// how Node.js instances are launched and communicated with. A new <see cref="INodeInstance"/> will be created
58+
/// automatically if the previous instance has terminated (e.g., because a source file changed).
6559
/// </summary>
6660
public Func<INodeInstance> NodeInstanceFactory { get; set; }
6761

src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
43
using System.Net.Http;
54
using System.Text;
65
using System.Text.RegularExpressions;
76
using System.Threading;
87
using System.Threading.Tasks;
9-
using Microsoft.Extensions.Logging;
108
using Newtonsoft.Json;
119
using Newtonsoft.Json.Serialization;
1210

@@ -36,21 +34,19 @@ internal class HttpNodeInstance : OutOfProcessNodeInstance
3634
private bool _disposed;
3735
private int _portNumber;
3836

39-
public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger,
40-
IDictionary<string, string> environmentVars, int invocationTimeoutMilliseconds, bool launchWithDebugging,
41-
int debuggingPort, int port = 0)
37+
public HttpNodeInstance(NodeServicesOptions options, int port = 0)
4238
: base(
4339
EmbeddedResourceReader.Read(
4440
typeof(HttpNodeInstance),
4541
"/Content/Node/entrypoint-http.js"),
46-
projectPath,
47-
watchFileExtensions,
42+
options.ProjectPath,
43+
options.WatchFileExtensions,
4844
MakeCommandLineOptions(port),
49-
nodeInstanceOutputLogger,
50-
environmentVars,
51-
invocationTimeoutMilliseconds,
52-
launchWithDebugging,
53-
debuggingPort)
45+
options.NodeInstanceOutputLogger,
46+
options.EnvironmentVariables,
47+
options.InvocationTimeoutMilliseconds,
48+
options.LaunchWithDebugging,
49+
options.DebuggingPort)
5450
{
5551
_client = new HttpClient();
5652
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
3+
namespace Microsoft.AspNetCore.NodeServices.HostingModels
4+
{
5+
/// <summary>
6+
/// Extension methods that help with populating a <see cref="NodeServicesOptions"/> object.
7+
/// </summary>
8+
public static class NodeServicesOptionsExtensions
9+
{
10+
/// <summary>
11+
/// Configures the <see cref="INodeServices"/> service so that it will use out-of-process
12+
/// Node.js instances and perform RPC calls over HTTP.
13+
/// </summary>
14+
public static void UseHttpHosting(this NodeServicesOptions options)
15+
{
16+
options.NodeInstanceFactory = () => new HttpNodeInstance(options);
17+
}
18+
19+
/// <summary>
20+
/// Configures the <see cref="INodeServices"/> service so that it will use out-of-process
21+
/// Node.js instances and perform RPC calls over binary sockets (on Windows, this is
22+
/// implemented as named pipes; on other platforms it uses domain sockets).
23+
/// </summary>
24+
public static void UseSocketHosting(this NodeServicesOptions options)
25+
{
26+
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
27+
options.NodeInstanceFactory = () => new SocketNodeInstance(options, pipeName);
28+
}
29+
}
30+
}

src/Microsoft.AspNetCore.NodeServices/HostingModels/SocketNodeInstance.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,19 @@ internal class SocketNodeInstance : OutOfProcessNodeInstance
4242
private string _socketAddress;
4343
private VirtualConnectionClient _virtualConnectionClient;
4444

45-
public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress,
46-
ILogger nodeInstanceOutputLogger, IDictionary<string, string> environmentVars,
47-
int invocationTimeoutMilliseconds, bool launchWithDebugging, int debuggingPort)
45+
public SocketNodeInstance(NodeServicesOptions options, string socketAddress)
4846
: base(
4947
EmbeddedResourceReader.Read(
5048
typeof(SocketNodeInstance),
5149
"/Content/Node/entrypoint-socket.js"),
52-
projectPath,
53-
watchFileExtensions,
50+
options.ProjectPath,
51+
options.WatchFileExtensions,
5452
MakeNewCommandLineOptions(socketAddress),
55-
nodeInstanceOutputLogger,
56-
environmentVars,
57-
invocationTimeoutMilliseconds,
58-
launchWithDebugging,
59-
debuggingPort)
53+
options.NodeInstanceOutputLogger,
54+
options.EnvironmentVariables,
55+
options.InvocationTimeoutMilliseconds,
56+
options.LaunchWithDebugging,
57+
options.DebuggingPort)
6058
{
6159
_socketAddress = socketAddress;
6260
}

src/Microsoft.AspNetCore.NodeServices/NodeServicesImpl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public Task<T> InvokeExportAsync<T>(CancellationToken cancellationToken, string
5050
return InvokeExportWithPossibleRetryAsync<T>(moduleName, exportedFunctionName, args, /* allowRetry */ true, cancellationToken);
5151
}
5252

53-
public async Task<T> InvokeExportWithPossibleRetryAsync<T>(string moduleName, string exportedFunctionName, object[] args, bool allowRetry, CancellationToken cancellationToken)
53+
private async Task<T> InvokeExportWithPossibleRetryAsync<T>(string moduleName, string exportedFunctionName, object[] args, bool allowRetry, CancellationToken cancellationToken)
5454
{
5555
ThrowAnyOutstandingDelayedDisposalException();
5656
var nodeInstance = GetOrCreateCurrentNodeInstance();

0 commit comments

Comments
 (0)