Dynamically loading and calling Rust code

Hi, I am looking for some help with understanding how dynamic loading works in Rust.
What I understand is that I can use the FFI to link extern libraries at runtime. Now my question is how practical this is for my use-case.
Say I have a client-server architecture, and I want to be able to receive Rust code from the client or server, compile it and link it with the running server or wasm client, then execute some code in it.

Would that be possible with a reasonable amount of overhead? Of course the compiler needs to run sometime, or are there some kind of "rusty" interpreted languages I could run through an interpreter?

Does anyone maybe have some experience with this or could someone explain to me how something like this would work?

Thanks a lot

Currently Rust is pretty unsuitable for this use case. How about using JavaScript? I guess it is not "rusty", but then you didn't define what that is, so I am at loss.

Hi there,
are you looking for something like a "Plugin" system ?
On another note this thread or this blog
might also give some answers for you - however, most of those approaches does not involve JIT compilation but assume the dynamic library is already build.

1 Like

As others have mentioned, this isn't a use case well supported by Rust. It's possible, but I don't think any good interfaces exist.

There are two hard parts here: first, compiling it, and second, linking it with the existing server.

For the first part, I think your best bets are either to just run rustc manually, using the CLI interface, or to have your clients compile the rust code before sending it to the server. Depending on what your clients are, one of these could be easier than the other.

For the second part, the most direct choice would be to compile to a dynamic library, and use libloading. You get direct calls to dynamically loaded dylibs, but the downside is that all of those calls need to be through a C interface, and you have the other constraints of FFI like needing to keep track of which side allocated things, and only free them on that side. abi_stable is a great rust crate for this, but even with that, it can still be clunky.

Another alternative would be to run your compiled rust code as a subprocess, and use an RPC interface to it. Kind of like how text editors use an RPC to talk to the language server - the language server runs as an independent binary, and the text editor uses it as a plugin by running that binary and talking to it via stdin/stdout. This does induce overhead. However, if there's any chance your code will crash, then this is definitely safer - crashing compiled code won't crash your whole service.

From your description, it seems like there might be more concerns, though. Do you trust your clients - in other words, are you willing to give them full user privileges on your machine? If so, then it's all good. If not, you probably want to look into sandboxing both the rustc execution, and the process you run the code in.

2 Likes

It might be worth trying to use WASM for this kind of use case. Michael-F-Bryan

3 Likes

You can make Rust a dynamic library (crate-type of cdylib) with a C API and use that with https://lib.rs/dlopen or https://lib.rs/libloading

2 Likes

Thanks to everyone. These solutions are still very much more "static" than interpreting code, so I am not yet sure if this is the right thing for my application.

@sanxiyn With "rusty" interpreted language I mean something that supports the Rust type system, but basically uses a modified reference model which is checked while interpreting. I think this would generally be an extremely valuable extension of Rusts ecosystem.

I just found Scripting languages for Rust.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.