-
-
Notifications
You must be signed in to change notification settings - Fork 268
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
Add Rust to the codebase #3007
Comments
I think a Rust backend would be great as a learning experience, but we'll have to see what others think about it. Then again, we'll need to rewrite ~10K lines of code and probably later the frontend as well. Who's going to work on that? |
We wouldn't be rewriting the entire thing, just bits and pieces where it might make sense. Plus, assuming we use PyO3, there wouldn't need to be any frontend rewriting - it would look just like another Python library to the frontend(s). |
I have no idea what the bottles codebase is but rust is good 👍 (in all seriousness, I’d be glad to help in my spare time) |
I really like the idea but I don't know Rust, nor the Python Rust interop. I would be happy to learn to rework some parts of the backend, I agree it would be better than Python in some parts! |
How would this work? Would the backend be a separate program that gets called by the frontend when doing things (similar to heroic)? Or would it be an actual library? |
It would be an actual library, just like it would be if you were to write a Python library in C or Go. Just an |
Doesn't that mean that we would have to also maintain python bindings for the library? |
That's where PyO3 comes in - I linked to an issue which gives some context. It's a bit of a pain right now, but I can write a macro that makes it easier to work with, so all we need to do is implement the Rust bits and add it to the macro. This is how it's done right now, this would be abstracted away with the macro I mentioned: use pyo3::prelude::*;
#[pyfunction]
fn double(x: usize) -> usize {
x * 2
}
#[pymodule]
fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(double, m)?)?;
Ok(())
} |
That seems like it could stack up to quite a bit of boilerplate code. Wouldn't it be a better idea to have the backend a seperate process that communicates via a unix socket or smiliar? That way the frontend could also be in a completely different language without having to create specific bindings. |
I'm not sure how I feel about this. I don't like the idea of writing the backend in two entirely different languages, even with abstractions. I rather fully commit to it or not commit at all. |
I don't think so, it might just be easier to have it be a Python library, so it more or less fits in how the backend does now. Plus this bit feels like it's deserving of a whole other discussion, and isn't really relevant here. The boilerplate shouldn't be too much - it should be a simple macro that expands to the full implementation. At most, I see three macros: one for structs, one for enums, and one for functions. That said, I need to implement it to see - I'm reading up on the maturin docs to see what would be necessary to get a hello world going. |
The way it's going to be implemented is very important to deciding if we go through with this, as different implementations can cause different maintenance efforts and generally different benefits. If we would go with using the backend as a daemon, it would be less code (no bothering with python bindings), people who want to create different frontends (for example in qt), wouldn't be forced to create their own bindings, but could just talk to a daemon. |
Having a full Rust backend would maybe be beneficial, but it's a long way to go to do that right now, so I think we should keep in mind the idea to replace everything with Rust, but we can't realistically do it in a short span of time anyway |
I don't expect it to take little time. If anything, I don't want that at all. I much rather have everyone take a long time to make it good than rush bad code and decisions. |
I don't want to fully commit to this all at once, because it could end up just not being worth it. That's why I'm going to start this off with a Hello World, then a simple rewrite of one of the backend utils. If both of those go well, we might be able to go all-in. But I don't think an all-or-nothing situation would benefit anyone here. That would lead to rushing bad code and decisions, as you mentioned. We can (from what I can see) easily integrate it here and there, within reason. But rewriting the entire backend is a major undertaking and will only make it harder to work on. Dip our toes in the shallow end, and see if we like it. Don't force us to cannonball into the deepest part of the pool. |
Agreed. There is the repo/download/startup séquence I would like to speed up, and I think Rust may be the way to make it way faster than what it is today. It would "just" be a chunk of the backend, but could benefit greatly end users by having a way more snappier startup of Bottles |
I am all for it. |
If we go with this idea, it should be seperate project and rust backend should be developed independently, to the point where it is possible to either use the backend as a drop in replacement with minor to none patches in the frontend. That way, in case we realize that a rust backend is not the way to go, we can drop it and it would not affect bottles in any way. If we only port specific parts to rust, we would not only have to maintain more codebases, but we are also more vulnerable to breakage as we now rely on pyo3. An exact discussion on how to do the rust backend is also necessary as I currently don't see pyo3 as a good option compared to having a daemon backend. |
@axtloss Today the frontend is already 100% disconnected from the backend, there's a signal/event system that makes the communication between the two when necessary. It is theoretically already possible to write another frontend fro Bottles. I think the approach with PyO3 is the better one in our case, switching to a daemon approach would be quite the work without much benefits imo |
No? I advocated for taking all the time we can to rewrite everything. Yes, it's a major undertaking, but so is adding Rust as a dependency - the majority of us don't know Rust, meanwhile every developer in the team, except you, know Python. We still haven't discussed about maintenance. Who's going to maintain it? So far, only you and @axtloss know Rust, so only the both of you might maintain it. If one of you don't want to maintain, then the bus factor would be incredibly low. Someone who knows Wine and Rust, and is interested in contributing to Bottles is going to be much harder to find.
I believe that adding Rust in an environment where most are unfamiliar with it is already a cannonball, so I prefer to have it tackled head on or to avoid it completely. |
The signal/event system would be exactly the same if using the backend as a daemon, the one added part would be having a reciever/sender function to communicate with the daemon. using pyo3 would make us rely on an external system that can break and require us to rewrite parts if pyo3 updates with breaking changes (which apparently already is the case based on the issue linked in the first issue message by oro) |
I think I'll close this as not planned for now.
The effort needed for this whole thing would be better put to improving the other places of the codebase, and maybe integrating more familiar languages like Go, which the developers are more intimate with, and would likely give many of the same benefits as Rust, due to also being compiled (and the garbage collector won't matter very much for Bottles). I'll be trying to learn Go here and there in the meantime to see if I can work myself up to adding that instead, and maybe we can work on improving Bottles with that where necessary instead. |
The main reasons to use Rust is faster processing and better error reporting when compared to Python (the Rust compiler give more rich logs), this will improve the Bottles stability when codebase changes happen. About the maintenance problem, it's better to use other repository to rewrite the backend in Rust and only developers with Rust skills will commit, that way there's no maintenance problems. Python developers on the Python backend and Rust developers on the Rust backend, of course the Rust backend will need to be updated to match API compatibility with the Python backend to not break the frontends. |
No need for So in
Also in the flatpak manifest you will have:
and a |
A Rust implementation also help in the packaging process, complex Python programs needs to use |
GO language looks great, but I would wait for MOJO language to be released. |
I've asked @mirkobrombin about this to see if he would be okay with trying it out, and I got the okay. I'd like to use this to see if any other contributors have any concerns.
I'd like to look at trialing Rust in Bottles internals. There are a few reasons for this, and a few that make it hard, but the main motivator is the Rust ecosystem, as well as the language itself.
Go is also another potential option, and the contributors to Bottles may already know it. However, I'm not familiar with Go <-> Python interop, and can't comment on the possibility of using it.
I would start this Rust integration off with a simple Hello World, then a rewrite of one of the backend utilities without using any external crates - the sandbox utility, specifically. Then we can move on to using third party crates. At each step, we would review the work, and see if it's worth keeping it.
If it's decided that Rust integration wouldn't be worth it, we can remove it - simple as that.
I don't have plans to rewrite any of the frontend(s) in Rust, just the backend.
Benefits
Pain points
CCing @TheEvilSkeleton @ItsJamie9494 @axtloss @jannuary @Kinsteen
The text was updated successfully, but these errors were encountered: