EDIT: The crate maintainer has now merged the offending PR and acknowledged an understanding gap regarding what unsafe
means in Rust. And so the wheel turns...
The Rust community is all up in arms about the actix-web
crate - again. I won't rehash the problem - here's the instigating blog post, the reddit discussion, and the GitHub PR discussion that people think is problematic.
Last time around, there was an uproar around what was perceived to be cavalier usage of unsafe
. Folks reviewed the code and found the usage to be unnecessary in a number of situations, and opened PRs to rewrite these portions using safe Rust without sacrificing performance.
This time around, the big bad is Undefined Behavior. A PR was opened that rewrites some unsafe code using safe Rust and as a side effect avoids some potential UB. The PR author provided an example of UB that this PR fixes.
The maintainer has opted not to merge the PR. Cue hellfire.
Now, some of this dissonance is Rust-specific. The actix-web
maintainer is catching all this flak because he is making design decisions that are perceived to be at odds with the core tenets of what Rust is and why people choose it over existing alternatives - namely safety.
However, this seems to be a much more human problem than a technical one. The crate author and maintainer - actix-web
is largely the work of a single human - doesn't seem to be too concerned about this problem and can't be bothered to address it.
This begs the question: who does actix-web
belong to? As an artifact of its infancy, the number of robust, production-ready web crates for Rust is small, and at this point actix-web
is the only option of its caliber that runs on stable Rust. Has this scarcity created an artificial sense of ownership on the part of the community? Or does this maintainer now actually have the real responsibility of reviewing and merging this PR he's personally uninterested in at the community's behest?
People are off-put by this maintainer's unwillingness to deal with this newly found UB problem. But is the maintainer in fact obligated to do so? Yes, the framework has a bunch o' stars and downloads, but that doesn't make it not this guy's project. The core rust async team is working on their own web framework, and with that crate we're having a different conversation. There is a reasonable expectation of quality from the Rust team. Here, though, the author has decided that he knows what he's doing and can write correct, performant code using unsafe
, and this instance of UB doesn't bother him in the context of this application. He's also understandably standoffish after the whole unsafe
debacle turned vitriolic and personal in nature last time around. I'd, too, be hesitant to act at the beck and call of what seems like a toxic and demanding community, for no compensation, to fix a problem that I don't personally perceive as a problem in the first place.
What's the solution? Never release software? I'd certainly hesitate to do so again were I this maintainer. Never rely on software that isn't supported by a large team? Often feasible, but not always, especially in a new and growing ecosystem like Rust.
Regardless of how you feel about "the spirit of Rust" and how software should be architected with it, it's undeniable that actix-web
is a good piece of software. It's fast and easy to use, even if it doesn't look inside like code you'd write in Rust. I don't know what the code to most libraries and frameworks I use looks like, though. When was the last time you opened up something like cairo
, a foundational piece of software that's widely distributed. Should its code style dictate whether or not you add it to your app's dependency tree?
This is a hard problem. I don't think there's "an answer". How do you approach these sorts of situations in the ecosystem of your choice?
Photo by Hermes Rivera on Unsplash
Top comments (14)
I, at least, am mostly upset that the README and home page don't have Warning: actix-web should not be used for production projects. Its API can be used in a way that produces undefined behavior, and you shouldn't stand for that. Specifically,
DataServiceInner::as_ref()
can produce an immutable reference to mutable data. on them like abomonation does.First of all, such a warning would be incorrect. As both the maintainer and the person who made the PR pointed out, the public API does not expose the bits that could result in UB.
Then I wholeheartedly disagree with your expectations. It's not the project maintainer's job to warn you or even provide documentation or code at all. It's your job to do your due diligence before you use third party code.
You don't like the documentation or code, or found bugs? Then ask (nicely) for changes and argue your case. Which is what people did here. Coming on a bit strong tho, as predictably a lot of people did some drive-by commenting in the PR.
Maintainer still doesn't budge, or doesn't even listen to you at all? Then fork. Or don't use the code.
But do not even pretend the maintainer owes you anything at all. Be it a warning in the documentation, or a response to your questions or PR, or the code itself.
How is that even a question? It belongs to the maintainer.
If the "community" wants to own it, then the "community" will either have to convince the maintainer to hand over decision making control to some community body, or the project has to be forked.
It's a question because the Rust community, generally a positive, constructive group, continues to act in a way that's at odds with what we both feel is obvious on its face - there is no entitlement.
I agree with you both on this matter. Harassing fafhrd91's personal email is not okay. Warning people off of actix-web like 64's blog post did, on the other hand, is not harassment. People have to be allowed to voice when they like or dislike a library, otherwise it's not possible to make an informed decision about what's safe to depend on and what isn't.
(I specifically didn't comment on Actix-Web's issue tracker, or open a pull request, since fafhrd91 is already overly-flooded with all this noise and fury. I wouldn't wish that on anyone, and I certainly don't want to add to it.)
100%. I came away from reading the post itself with no negative feelings at all. Reddit has a way of changing that, I guess.
People do have to be allowed to voice this sort of thing without worrying about this sort of reaction. The concern raised about the nature of what "safe Rust" guarantees is absolutely, 100% legitimate and something people should be informed of when deciding whether or not to use the tool. It's a real problem that we can't just be friggin' cool for once.
Agreed - there is a clear documentation gap.
Ben - I'm sorry, this turns into a rant. Please forgive me and extract the useful bits π
Damn straight it's hard. One of the reasons I left Rust behind (about two years ago) was the focus on Nightly by Rocket - it seemed insane that what was (at the time anyway) the most popular web framework in the language relied on the version of Rust with a shifting API (and I see it still does - madness). A language that ostensibly prides itself on stability and correctness shouldn't really have a Nightly channel with big projects depending on it. It shouldn't have a Nightly channel at all.
I was unaware of
actix-web
but I can't say I'm surprised - the maintainer has obviously decided that correctness is not as important as raw speed - as the examples from the WebFramework Benchmarks show - or his ego.Regarding raw speed - I saw the same nonsense kick off in the Go community a few years ago as every framework maintainer built and boasted of the 'fastest' HTTP framework like they were racing muscle cars down the L.A. River. I see nothing's changed. It's such a ... ridiculously empty metric. Frameworks can be as quick as you like, but if your code isn't maintainable, and the framework isn't stable, then it's really not worth it. The latency from a slow web server is - to my mind - usually negligible unless it's really slow.
Anyway, to answer your point: how do I approach this in the ecosystem of my choice?
My ecosystem of choice is Go, and I choose - usually with an irritatingly iron will - to only use the standard library if I can bloody well help it.
An horrific experience with NodeJS (ah, left pad) left me highly suspicious of dependencies which were themselves towers of dependencies (another criticism of
actix-web
- and almost all modern frontend development). What I like about Go is the way that the language is very, very stable - almost pathologically so. And the standard library is good enough. No, it's not the fastest HTTP library - not even the fastest one in Go. But it's fast enough, well documented, and very nice to read if you have a mind to of an afternoon, or if you're wondering just how it is that the HTTP headers get parsed. You feel as safe and comfortable using it as you do using thestrings
library, or adding two numbers together.Now how would I approach this 'wonder framework' or
actix-web
? I'd try and ignore it until it goes away - which it will. The developer will get bored of it, or get a job, or move on to yet another language in which to build Greased Lightning and - poof - all of a sudden there are no maintainers and a mess of unmaintainable code and a thousand developers screaming in the wilderness about how it isn't fair.Well, bully. If you favour hype and speed over maintainability and community then you deserve everything you get in the end.
Yes, Rocket was what drew me to Rust, and Nightly is what drew me away from Rocket. It felt crazy to me at the time, quality of the framework aside. That's why I hopped to
actix-web
the moment I heard about it - similar functionality but stable rust, and this whole coolActor
idea to boot, which isn't really relevant anymore.That's the thing about Go I liked. The standard library gets you way further than you expect. I should give it another shot someday.
This is rough, because
actix-web
was specifically a situation which I had hoped was avoiding all this, and headed towards the latter two. I guess it remains to be see how it all shakes out - meanwhile I'll do my servers in something else with an eye on tide once async/await stabilizes. I think that's as close to the Go-style stable standard way of doing things as we'll get for a while, and it looks pretty good...but relying on a language feature that hasn't even landed yet means we're a ways away from anything robust.This is why forks happen and why some free/open source "feuds" in the form of forks can last for years.
If half the community is okay with unsafe and undefined behaviour in one or more of their Rust dependencies, that's cool, but there will be another fork that isn't okay with it for the other half of the community.
I remember years ago when learning the D programming language that the standard library wasn't very good and there was a competing standard library. Basically you voted with your feet as a user by using whichever library you thought was better, and as a developer by contributing patches. If someone feels strongly enough about actix-web, they'll start a "safe-actix-web" fork and maintain and start accepting patches and incorporating the ones that already exist.
Steve has this to say - which is about right:
We need more communicators like Steve.
If someone is really upset about it and thinks their way is better they should fork it and let the better code survive.
True, or you've now splintered an already minuscule community into oblivion and both die. I don't really know how it'd play out.
First off, I'm not a Rust dev. However, I work every day in the Python ecosystem which has an equally passionate community that, I believe, Rust will one day grow to equal in size.
That being said, I believe that seeing this as an issue that can only be properly talked about with members of the ecosystem is folly. All language/framework/ecosystem communities suffer from the same problem in OSS: forgetting that the software is volunteer-produced and FREE TO USE!!!
In what other part of life do we get something literally handed to us totally free, and have any leg whatsoever to stand on to demand anything from the person who is giving it away? Most open sourcers are not paid for their time at all. Many of them work secular jobs, have families, friends, and lives that are much more demanding and important than the whims of those reaping the fruits of their labor totally without compensation.
If you don't like an OSS package, don't use it. Respect the maintainer as a human who is, quite literally, taking time away from their personal life to give away a piece of software that might otherwise not exist. We should be floored with respect that somebody cares enough about people and their community to take time away from their busy life to solve a problem they know people struggle with and have no solution to.
If you are a Patreon supporter of a dev who does something you don't like, that's fine. If you have a constructive way to voice your concern, please do it. That's the beauty of OSS! But how spoiled are we that we get to have somebody else solve our problems at their own expense, then turn around and say "yeah, but did you do it the way I like? Cuz I only like stuff done this way..."
Here's an alternative: if this Rust web framework that you're using for free is SO bad, then go find a similar toolchain in Rust that you can purchase a license for, then pay the extra monthly fee for their extended support plan. Don't want to do that? Then respect the developers time, expense, blood, sweat and tears and wait. Or find another project. You're a developer too and know how many keyboard warriors come out if the woodwork to say "ur code sux. You should stick the cleaning dishes at Denny's cuz ur a total noob!" the moment you write something that gains a little popularity. don't be part of the trolling and super unhelpful and destructive problem that can make all of us want to change careers at some point and time.