SteveSandersonMS / dotnet-wasi-sdk

Packages for building .NET projects as standalone WASI-compliant modules
519 stars 36 forks source link

Cannot create a GRPC channel inside wasm at runtime and question on exposing c# functions #26

Closed douglaswaights closed 2 years ago

douglaswaights commented 2 years ago

Hi,

I'm using .net 7 preview 6 and wasmtime-cli 0.40.0. using wasi sdk 0.1.1

If i try and create a grpc channel with the following code in program.cs

using Grpc.Net.Client;
Console.WriteLine("before the channel");
using var channel = GrpcChannel.ForAddress("<redacted>");
Console.WriteLine("created the channel");
'C:\Program Files\Wasmtime\bin\wasmtime.exe' --dir=. .\ExampleCmdlineConnector\bin\Debug\net7.0\ExampleCmdlineConnector.wasm
before the channel
[wasm_trace_logger] cant resolve internal call to "Interop/Runtime::GetGlobalObjectRef" (tested without signature also)

Your mono runtime and class libraries are out of sync.
The out of sync library is: System.Private.Runtime.InteropServices.JavaScript.dll

When you update one from git you need to update, compile and install
the other too.
Do not report this as a bug unless you're sure you have updated correctly:
you probably have a broken mono install.
If you see other errors or faults after this message they are probably related
and you need to fix your mono install first.

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'System.Net.Http.BrowserHttpHandler' threw an exception.
 ---> System.MissingMethodException:  assembly:<unknown assembly> type:<unknown type> member:(null)
   at Interop.Runtime.GetGlobalObject(String str)
   at System.Runtime.InteropServices.JavaScript.Runtime.GetGlobalObject(String str)
   at System.Net.Http.BrowserHttpHandler..cctor()
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpClientHandler..ctor()
   at Grpc.Shared.HttpHandlerFactory.CreatePrimaryHandler()
   at Grpc.Net.Client.GrpcChannel.CreateInternalHttpInvoker(HttpMessageHandler handler)
   at Grpc.Net.Client.GrpcChannel..ctor(Uri address, GrpcChannelOptions channelOptions)
   at Grpc.Net.Client.GrpcChannel.ForAddress(Uri address, GrpcChannelOptions channelOptions)
   at Grpc.Net.Client.GrpcChannel.ForAddress(String address, GrpcChannelOptions channelOptions)
   at Grpc.Net.Client.GrpcChannel.ForAddress(String address)
   at Program.<Main>$(String[] args)

I realise this is all highly experimental but is this something that is expected to work? I guess not right now. I had high hopes after seeing the Greenhouse Monitor demo :-) although i appreciate that was a server rather than client.

I was also wondering more generally about using C# wasm in a more faas orientated / plugin style. I would like to build a C# wasm module that exposes functions i somehow declare in C# and then can call via wasmtime embedded in another host application. Is this possible?

Regards Doug

SteveSandersonMS commented 2 years ago

is this something that is expected to work

Unfortunately not at this stage, at least not on a bare-metal WASI runtime.

The WASI spec itself doesn't yet contain any outbound networking, so you can't have a gRPC client or even an HTTP client (whereas you can have a gRPC server or an HTTP server).

Everyone in the WASI community is keenly aware of how important and urgent it is to fix these massive gaps and is working towards that. Hopefully the WebAssembly Component Model spec, when ratified, will make it possible to move far faster with expanding the scope of what WASI can do.

In the meantime it's technically possible to implement your own WASI host environment that adds custom native functionality so you could implement your own custom outbound networking. That's how all the FaaS-on-Wasm services work today. But it's nontrivial to implement and involves having deep understanding of the whole stack.

I was also wondering more generally about using C# wasm in a more faas orientated / plugin style. I would like to build a C# wasm module that exposes functions i somehow declare in C# and then can call via wasmtime embedded in another host application. Is this possible?

Yes, for example see how the https://github.com/SteveSandersonMS/dotnet-wasi-sdk/tree/main/src/Wasi.AspNetCore.Server.CustomHost sample exposes custom imports/exports for the wasm code and calls it from a custom host. It's pretty difficult and low-level at the moment, but https://github.com/SteveSandersonMS/dotnet-wasi-sdk/issues/30 should be the solution to make this friendly and only require writing familiar C# code.

douglaswaights commented 2 years ago

@SteveSandersonMS Thanks very much for the comprehensive reply. This makes sense!