New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Implement .NET Host SDK #119
Conversation
Hey @mhmd-azeez; external observer, thanks for raising this PR! Let me know if you want any assistance, I've got use-cases in mind... Have you considered generating a native-assembly nuget package that contains a pre-built extism binary for various platforms? Similar to how (https://github.com/jedisct1/libsodium/actions/runs/3560505523)[libsodium does it]? That would give a nice out-of-the-box experience for .NET devs. Your may choose not to include Android and iOS builds in there by default out of the pain of setting up those builds, but desktop and server platforms should be fairly straightforward? |
Hello @alistairjevans I definitely plan to generate native assembly nuget packages. And if you're interested, we can work on this PR together. @nilslice mentioned that they can drop the binaries in a folder in GitHub actions |
Sure, I'm up for helping out; how you want to do it? I can fork your repo and merge into there to make this work? Or collaborate on your repo directly? Your choice. |
Fantastic! @alistairjevans I just invited you to my repo, do you agree with the scope in the PR description? My idea is to get something up and running and then in subsequent PRs add more layers and nice-to-haves and even a .NET PDK |
Yeah, I think the scope makes sense; to my mind, step 1 is to build a solid (but thin) interop layer over the imported methods, and get that CI and tests in place. There's always going to be people who want to be able to reach directly for the methods that work with raw Once that's in place, a higher-level API that helps with serialising data to/from the plugins, a POCO representation of the manifest, and so on, will help most users pick this up more easily. I haven't seen that there's a fixed standard for passing structured types to/from the PDK; JSON seems to be included in the PDK by default, but it's a relatively inefficient format for passing arguments, so I can imagine guidance (codegen?) in future for defining interop data structures. I wonder if @nilslice has considered anything like a protobuf-style spec for defining parameters to plugin methods; this would allow you to arrive at a standard structure definition for all the supported PDKs from a single source. The use-case I'm thinking about for this is plugins for processing network packets in near-real-time, so would want to keep the method argument passing overheads low. It looks like you can only pass a single data pointer to each plugin method, and I'm assuming that the data is copied into the WebAssembly context rather than providing direct access to the provided buffer. |
Hey @mhmd-azeez I'd be happy to take some of these tasks if you don't want to do them:
|
Okay we now have a Nuget API key stored as github secret: |
@bhelx Thank you very much! Testing is something your help will speed things up and as for the pipeline I'll need your help in fetching the native binaries. Will let you know once I get there |
> I'll need your help in fetching the native binaries. Will let you know once I get there
I can look into this as well. we may have to build it on the fly
…On Dec 2, 2022 at 10:53 AM -0600, Muhammad Azeez ***@***.***>, wrote:
@bhelx Thank you very much! Testing is something your help will speed things up and as for the pipeline I'll need your help in fetching the native binaries. Will let you know once I get there
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@bhelx how can I make sure that logging works? currently I set log level to Edit: I just pushed some code that I used to test the logging, I haven't been able to force it to write anything to the log file so far. |
I seem to recall @nilslice or @zshipko may have something to say on this. I noticed this issue in another host library. May be a bug that we should track and fix. If it's returning true though I say keep going and don't worry about it! It should error out if you are doing it wrong |
Looks like the logging issue is a bug - I just made a PR with a fix: #123 |
For the nuget packages, I think OpenCVSharp's approach is a good fit because Extism's binaries are pretty big (10 - 30 MB per platform). So we shouldn't force people to copy all of these binaries with their apps. Here is what I have in mind:
This gives the user freedom to use the systemwide installations or include specific binaries with their apps. These are the OpenCVSharp packages: https://www.nuget.org/profiles/schimatk @alistairjevans what do you think? Note 1: I think if we go through that route, we should publish the runtime nuget packages in the https://github.com/extism/extism/actions/workflows/release.yml pipeline since these packages deployments don't have anything to do with the C# code. We can create a new pipeline that only publishes the Note 2: Including the binaries is mostly important for Windows, because extism already supports systemwide installation for macOS and linux. So we can even skip them. @bhelx @nilslice Note 3: The runtime names are based on .NET's runtime identifiers. |
I am not sure I really know the impact of deciding either one. Are there many Windows users who use the
I think we can skip these for macos and linux. This is assuming that dotnet doesn't expect any special treatment on those platforms with regard to how it locates shared libraries. I think it would use the system's linker anyway? |
Do you think there's a reason not to lay claim to the I would then be tempted to ship I think storing the runtime packages separately is a good idea. Would suggest a couple of things:
|
+1 to naming |
Since publishing these packages is fairly straightforward, I think we should just publish for all 3 platforms.
I didn't include it because release artifacts don't have it. If @nilslice @bhelx think it's possible, then we should definitely add it. @alistairjevans I agree with your naming suggestions, I will rename the projects accordingly
Great idea And as for the win binary, let's go with the MSVC one just because it's smaller (however as @alistairjevans mentioned, requires the VC++ redist runtime) |
I don't have strong feelings against using the
Rust can target that platform, but I don't see a release for it for one of our dependencies https://github.com/bytecodealliance/wasmtime/releases/tag/v3.0.1 I haven't tested to see if it wouldn't build, but I'd imagine |
On second thought, maybe we should keep things consistent with the other platforms, @alistairjevans @bhelx what do you think? |
Sorry catching up here. I understand the reason we may want to put the dll in the package for windows users, since they expect that. but for everything else we should probably follow the pattern we have with the rest of the libraries. Let the FFI library search out the |
Yeah I think consistency is key unless there is a strong idiomatic (dotnet) reason to break it. |
man one other thing i need to do, make a table of architectures and OSs we support. |
Happy with that argument @bhelx. Extism.Sdk it is then. Re: distributing the binaries; on non-windows system, what's the deployment approach? Build from source on-device and put the built binary in the load path? I guess to keep things simple and consistent we can start with that, but dotnet users are generally less familiar with build-from-source-libraries on any platform, so I can see some challenges on that front in the future. |
For linux and mac, we have an installer that manages the dynamic library. it puts it on your load path: https://extism.org/docs/install#macos-1 The SDKs find this library at runtime. For windows I'd defer to your judgement. We probably want to have some code that just loads the packaged version for windows and finds the installed version for other platforms. |
I don't mind going with the approach of only releasing the windows runtime nuget package. But I just wanted to clarify the process a bit so that both @bhelx and @nilslice have a clearer understanding of the future maintenance work. So .NET has its own search path in addition to the OS search path, it's something like this: The
The
The
Now, we can either add all of these to a single nuget package, or separate them into different nuget pacakages. The important part is, as you might have noticed, these nuget packages contain nothing .NET specific, so they can be published whenever a new version of We will have two other nuget packages: Now, whichever path you decide is totally fine with me because I understand your concerns as the library maintainers. |
It will certainly be faster - and I think we always want to ship an SDK to target the latest release anyway. The only tricky thing I can think of is when we make a runtime release, we have to also re-release the .NET SDK so that it bundles the latest runtime. This might turn out to be true for most runtime releases anyways (especially for runtime feature additions/changes) but worth calling out and thinking through now. Awesome work @mhmd-azeez!! |
Just wanted to clarify one thing, the .NET SDK doesn't bundle the runtime. The So the release cycle of |
…dless of working directory
I'll take a look on Monday @mhmd-azeez; I'm away-from-keyboard until then I'm afraid. |
… Context and Plugin classes provide comprehensive wrappers for the underlying library. Also implement thread-safe dispose semantics and verify Context and Plugin have not been disposed when invoking methods.
Make interop calls internal, plus some other minor bits.
@mhmd-azeez regarding:
I have some pre-compiled wasm modules in this repo, which I use as an example. https://github.com/extism/extism-fsnotify/tree/main/apps Both plugins use these datatypes as input/ouput in JSON: It may be useful to re-use them! |
@mhmd-azeez trying to understand what is needed from us to get this published. Are you saying this is how it works now? Or do you need us to work on the CI task to get the dll in the right place? As for testing. I think it's in a good spot. If you want I can add some more unit tests tomorrow. As for testing different plugins, so much of that logic happens in the runtime itself so i think testing different plugins has diminishing returns. We just need to make sure we're mapping the types correctly back and forth. Unit tests can address this. Let me know what you think. We're already got a few people stoked to try this! |
Hello @bhelx
Unfortunately it doesn't work like that right now, so you'll need to work on the CI task to get the dll in the right place. If you can put the MSVC dll in Edit: I edited the PR description to cleanup the tasks |
After this PR is merged, I will try to work on adding a page on the extism docs about the .NET SDK |
Hey @mhmd-azeez I have some notes on the interface: mhmd-azeez#3 In the rest of the libraries, we hide the implementation details of libextism. no need to expose length and error for example. I changed the interface of |
our docs repo isn't public yet. I'm happy to do that for you. I can send a preview link here for you to approve. |
Heads Up: Github does not seem to want to allow us to run these release workflows until we merge. So we can merge this when the code is ready and follow up to fix the workflows. |
The branch with the doc changes is here: https://dotnet-sdk-doc.extism-docs.pages.dev/docs/integrate-into-your-codebase/dotnet-host-sdk/ Will update this after we merge, publish, and test it. Once we verify the instructions are working we'll go live with it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, great work on this!
@bhelx thank you very much. This makes me so happy :'D A couple of notes:
After mhmd-azeez#3 is merged we should merge this PR too I think |
Yes, i think it's time to merge it and let's do some smaller, more focused, follow up PRs. Great work getting it this far! Ping me when you want to merge mhmd-azeez#3 . Is there anything else we need to do for it? I'll update the docs site with your suggestions too, thank you! |
…interface-changes feat: hide some of the implementation details of libextism
I just realized i can merge it. Let's get all this merged up now! Just gonna wait on CI one more time. |
Let's go! |
Wohooo! 🎉🎉🎉 |
I am working on a .NET host for extism. My plan is to do the following:
ci.yml
to include .NET Sdkrelease-dotnet.yml
to releaseExtism.Sdk
nuget packagerelease-dotnet-native.yml
to releaseExtism.runtime.win
nuget packageEdit README show that the there is a .NET SDK. Probably we should not do this until we have a docs page.Use theExtism.runtime.win-x64
package in the sample projectOut of scope for this PR: