This week on Herding Code, the guys talk to Tomasz Janczuk about running .NET code in Node.js using Edge.js.
Download / Listen:
Herding Code 166: Tomasz Janczuk on Edge.js [audio:http://herdingcode.com/wp-content/uploads/HerdingCode-0166-EdgeJS.mp3]
- Intro and background on Edge.js
- (00:40) Tomasz has been focusing on Node.js at Microsoft for the past 3 years. He’s been working on making Node.js run well on Windows. He’s also worked on hosting Node.js on Windows Azure with IISNode.
- (02:08) Jon asks about Edge.js’s original name, Owin. Tomasz explains how that made sense with the original scope – connect middleware and express handlers – but it’s grown since then so it needed a more generic name.
- (02:45) Edge.js lets you run Node.js and .NET code in one process and provides interop mechanisms between the two.
- (03:05) Jon asks why that’s useful. Tomasz says you can do pretty much anything in either Node.js or .NET, but some things work a lot better on one platform. He gives examples like using ADO.NET to connect to SQL Server and running CPU bound computations as multi-threaded .NET code from the single-threaded Node.js event loop. There are two classes of scenarios: things that work better on one platform, or writing native extensions to Node.js without having to drop all the way down to raw C and native OS mechanisms.
- (06:11) Jon brings up two questions from Twitter about Mono support (Jason Denizac @_jden "when’s mono support coming?" and Kevin Swiber "Mono support? Can we do legit Node modules in C#? Are grilled hotdogs really better than boiled?" Tomasz says not yet, but it’s high on the list. There are some complications to implement that support since Edge.js uses C++ CLI, which isn’t available on Mono.
- Getting started and samples
- (07:57) Jon asks what’s involved in setting it up. He says he ran npm install edge, then npm install edge-cs. Tomasz explains why he didn’t need to install edge-cs – C# support is built in, other language support plugs in.
- (08:43) Jon asks about the samples. Tomasz explains the different ways of integrating CLR code into Node.js and talks about how the samples show these approaches.
- (10:36) Jon says he liked how the samples progressed from very basic to pretty complex. Tomasz says you can do just about anything in Edge.js, but there’s a specific interface you need to follow in order to work smoothly between the Node.js async model and many synchronous operations in .NET. Every function in Edge.js uses an async function delegate, so you end up using small wrapper functions in some cases.
- Marshalling and interop
- (13:08) Kevin says this reminds him of COM / .NET interop and issues with object lifetime, garbage collection, etc. Tomasz says that that the async function delegate solves the threading models. Object lifetimes are controlled because everything is marshalled by value.
- (16:22) Kevin asks if the marshal by value prevents working directly with the CLR object. Tomasz says that you can handle this using function proxies to create closures over CLR states.
- (21:25) Jon says he thinks this sounds useful for using a NuGet package in a Node.js application and asks if there’s support for pulling in a NuGet package. Tomasz says that at this point it’s up to you how you’d get the assembly downloaded and set up, but that there’s an open issue to get script-cs integration going and that would handle this.
- Overhead and performance
- (23:06) Jon asks about the overhead of running two virtual machines and marshalling. Tomasz says there is some overhead, but it’s better than running two different processes. Edge.js is built for solving some specific scenarios, and it’s fast in those
- (24:55) Kevin asks if there’s a delay when Edge.js spins up. Tomasz says that happens when you require Edge, but it’s not really noticeable.
- Misc questions
- (25:55) Jon asks what was the hardest part of implementing Edge.js. Tomasz says the function proxies to handle lifetimes and reconciling threading models.
- (27:45) Scott says this sounds useful for authentication or using a legacy .NET library. Tomasz lists several more.
- (29:20) Kevin asks how exceptions are handled. Tomasz explains how the exceptions are marshalled and thrown across VM boundaries.
- (30:15) Kevin asks if it’s tied to specific Node.js versions. Tomasz says it works on all current stable versions.
- (31:30) Question from Twitter: @jeremydmiller "I’ve seen a lot of samples of hosting . Net in node, but how about running node in a .net process?" Tomasz talks about an open issue, Mission Double Edge which would handle that. He explains that the challenge is that Node.js doesn’t have a hosting model.
- (33:20) Jon says he saw several of the samples had the C# script named with .CSX extension and asks about that. Tomasz says that this is partly done to follow Roslyn conventions, including specifying assemblies as references in code using #r.
- Future plans and next steps for listeners
- (34:25) Jon asks what’s planned going forward. Tomasz talks about Mono support and adding support for additional languages, including F# (note: this has been added http://tjanczuk.github.io/edge/#/3) . Jon asks what’s involved in adding language support.
- (36:30) Jon asks about the relationship with OWIN. Tomasz says there’s a separate module which allows you to plug any OWIN compatible .NET application and plug it into an Express.js pipeline. Jon says this reminds him of the Edge name and Tomasz explains that the idea is that mathematically an edge connects two nodes, so Edge.js connects differe.
- (38:25) Jon asks about next steps for people to get started.
- (38:55) Jon asks if this is a Microsoft project. Tomasz says it’s his own separate open source project that’s inspired by his day job, and this allows him some more flexibility to work with the community. He lists some of the community contributions they’ve seen so far.