Shared Object Support?

I doubt this is the case, but is there by chance a way to compile mojo to linux shared objects? If not is there any plan to include the ability in the future? Even if they cant cross operate with other executables coded in languages other than mojo, they'd be super useful for a project I have in mind.
17 Replies
Darkmatter
Darkmatter3mo ago
Shared objects cause a lot of issues for languages with generics. C++ has made a lot of language-level sacrifices to support them. Right now Mojo does not have a stable ABI, which means shared objects would need to expose a C ABI, which removes most of the good features of Mojo. I ran into this issue with Rust and found that using shared memory IPC or unix sockets and having one program per language was sufficient for almost all cases. If you want a plugin system, the way this is typically done is to round-trip via the C ABI. Mojo will eventually get clean interop with C/C++, and I think Rust interop may be doable.
Jabadahut50
Jabadahut50OP3mo ago
Ah damn. My project in mind was to reimplement Erlang's BEAM engine in MOJO but in native compiled MOJO rather than on a VM. The shared objects idea was to make hot swap-ability of code viable. Back to the drawing board to figure out something else then XD. Thanks @Owen Hilyard
ModularBot
ModularBot3mo ago
Congrats @Jabadahut50, you just advanced to level 2!
Jabadahut50
Jabadahut50OP3mo ago
Shared memory IPC could work but that'd be a LOT of individual processes. I feel like it'd eat a lot of RAM. May just have to wait for some updates or something if I can't figure out a different way to do it. @Owen Hilyard follow up question... is there per chance a way to compile mojo to MLIR bytecode? The bytecode format is fairly well documented and I know MOJO gets compiled down to MLIR before machine language anyway... and while i'd prefer compiled machine code, creating a bytecode interpreter could be another way of getting the functionality I want without too much performance sacrifice?
Darkmatter
Darkmatter3mo ago
I don't think the current compiler allows that. Mojo has a JIT mode (used in the REPL and notebooks), so you may be able to use that once it comes out, it should still be faster than BEAM.
Jabadahut50
Jabadahut50OP3mo ago
That could work... guess I'll be waiting for that then. Appreciate it.
Darkmatter
Darkmatter3mo ago
By the way, if you are doing that wait until I finish writing async IO to implement IO. The interface is going to look a little weird but should give you some options that are better than what production BEAM does right now for message passing.
Jabadahut50
Jabadahut50OP3mo ago
oooh now i'm even more impatiantley waiting XD so update... there IS a way to do shared objects... it's just an undocumented feature (aka they may make breaking changes to it so they don't want anyone relying on it incase it breaks later as Mojo is taking the rust approach to backwards compatibility)
sb
sb3mo ago
I've approached something similar in the past, the best solution I could come up with was something along the line of having orchestrator and runners be separate processes. Version the runners, and define a mechanism for determining what flow is allowed through versions for a given entry It's clunkier in some ways, but gets you most of the way there
Jabadahut50
Jabadahut50OP3mo ago
yeah Owen mentioned the idea of Shared IPC's which is a possibility but I worry how much ram it might eat doing all the runners as individual processes
Darkmatter
Darkmatter3mo ago
It would be per deployment, which is an important distinction.
sb
sb3mo ago
The runners don't have to be per-actor is my thought That spares you from having to slim things down quite as much as you would have to for something as flexible as beam
Darkmatter
Darkmatter3mo ago
Or, you can have one central "router" which does nothing but pass messages around and possibly do networking. With a good ring buffer implementation, a single core can bounce hundreds of millions of messages per second between buffers.
Jabadahut50
Jabadahut50OP3mo ago
I planned on having a dedicated thread for scheduling.
Darkmatter
Darkmatter3mo ago
I think that there are a few routes for scheduling. 1. You can do a single scheduler thread and use signals to preempt tasks. 2. Thread per core, tasks never move between cores. (Easy to implement, removes Send/Sync requirements, etc). 3. Thread per core with work stealing. This handles unpredictable workloads better, but can cause issues since it requires than all tasks are Send. Using signals isn't always great and can require some very fiddly unsafe, so I think that cooperative scheduling may be a better idea, especially since large servers tend to not like when a core is sending signals over the place (except for sapphire rapids with the userspace interrupts work, which is VERY specific to that hardware).
Jabadahut50
Jabadahut50OP3mo ago
a fair point... it'll require extra work but I think a work stealing scheduler is probably the better option the thing i've always wondered is everytime I read about the actor model everyone says "It eliminates race conditions" but if you're doing a multicore work stealing architecture wouldn't you potentially run into message appending as a race condition?
sb
sb3mo ago
Allowing work stealing is not that much of a lift, though I would avoid preemption--just relax any requirements that a task may run at most once and make it so you can roughly detect when tasks have gone off the rails In those cases, isolate them so that they trap themselves and quit at the next reasonable boundary, cut off their ability to commit their work, and spawn a new instance of the task You could potentially set up a way to kill that entire runner if it gets consumed by some accidental while(true) bugs, but you can't really stop things at the level of a single thread (and if you could you'd be opening yourself up to some very broken partial state)
Want results from more Discord servers?
Add your server