TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Giving up on wlroots-rs

283 点作者 Bl4ckb0ne大约 6 年前

19 条评论

steveklabnik大约 6 年前
A good post, thanks for sharing.<p>&gt; I want to make one (mildly controversial) thing clear: rewriting a library for the sake of only using Rust is not good engineering.<p>Strong agree.<p>&gt; A literal rewrite of a project to Rust is not interesting, it’s not useful, it just causes churn and splits ecosystems. Time would be better spent either working with existing solutions that already have the effort put in to make them correct or to come up with new green-field projects.<p>This... I&#x27;m not so sure about. It really depends on what your objective is. For example, if your goal is to learn, you&#x27;re not going to cause churn, and you&#x27;re not going to split ecosystems. Working on project you already know well is a good way to learn, because you can focus on the language, not the project.<p>This also isn&#x27;t <i>exactly</i> a re-write, in my mind. I mean it is, and it isn&#x27;t. This is because...<p>&gt; The biggest problem when wrapping wlroots was defining the ownership model of the objects that wlroots exposes.<p>The pain here isn&#x27;t a re-write, it&#x27;s an integration with an existing system. That&#x27;s a good reason to not use something different! I also think this is interesting because it demonstrates something that&#x27;s often said in discussions about Rust, but mostly in the abstract, and that&#x27;s that Rust&#x27;s rules influence the design of your system. It will guide you away from designs where the ownership of components is unclear. To many people, this is a benefit, but it can often cause struggles when learning. And, it can often cause struggles in situations like this: where you <i>can&#x27;t</i> really re-write some external component to fit in the rules.<p>That being said, there should be a way to do the ownership part that makes sense, but I don&#x27;t know wlroots well enough to comment.<p><i>That</i> being said<p>&gt; Currently there is 11 THOUSAND lines of Rust in wlroots-rs. All of this code is just wrapper code, it doesn’t do anything but memory management.<p>is also super legit. Managing this kind of thing is a pain. I can certainly understand not wanting to do it.
评论 #19779155 未加载
评论 #19779611 未加载
评论 #19779894 未加载
评论 #19779570 未加载
评论 #19780370 未加载
quietbritishjim大约 6 年前
I know very little about Rust or Wayland (I suppose I&#x27;m not the target audience) but I got lost very quickly here:<p>&gt; A Wayland “output” is the resource that represents a display device. Commonly this means it handles a computer monitor. This resource could disappear at any time in the life cycle of the application. This is easy enough to imagine: all it takes is a yank of the display’s power cord and the monitor goes away.<p>Surely even if a physical monitor is connected from a computer, the object representing it doesn&#x27;t instantly go away? If it literally got freed as soon as the user disconnected the monitor then any access to such an object would be dangerous as you could be accessing an object after it&#x27;s freed, or even another valid display object that got allocated into that space in the mean time.<p>Instead, I would expect an object in that situation to go into some error state, and even that might only be picked up when you perform certain operations. If that were the case, I don&#x27;t really see how Rust lifetimes are a problem.<p>Since this was the main summary of the problem for laypeople like me, it made the rest of the article quite hard to follow.
评论 #19779229 未加载
评论 #19779221 未加载
评论 #19779140 未加载
Diggsey大约 6 年前
I can&#x27;t speak to every issue which the author might have encountered, but there is a better solution to the lifetime management problem than the two mentioned in the article.<p>Instead of this:<p><pre><code> fn some_wlroots_callback(output_handle: OutputHandle, surface_handle: SurfaceHandle) { output_handle.run(|output| { surface_handle.run(|surface| { &#x2F;&#x2F; maybe some more nested layers... }).unwrap() }).unwrap() } </code></pre> One can do this:<p><pre><code> fn some_wlroots_callback( ctx: CallbackContext, output_handle: OutputHandle, surface_handle: SurfaceHandle ) { let output = ctx.get(output_handle); let surface = ctx.get(surface_handle); } </code></pre> This is safe, because the lifetime of &quot;output&quot; and &quot;surface&quot; can be bound to the lifetime of the &quot;ctx&quot; (whose lifetime is controlled by the library: the library simply has to make sure that &quot;ctx&quot; is not accessible outside of a callback).<p>edit: Realised you can&#x27;t tell that there&#x27;s an implicit lifetime in `CallbackContext` here:<p><pre><code> struct CallbackContext&lt;&#x27;a&gt; { ... }; </code></pre> OR<p><pre><code> type CallbackContext&lt;&#x27;a&gt; = &amp;&#x27;a CallbackContextImpl;</code></pre>
评论 #19779479 未加载
评论 #19779886 未加载
ChrisRR大约 6 年前
Interesting to see someone&#x27;s reasons for moving back from rust to C. Normally it&#x27;s the other way round.<p>Speaking as a C developer who has dabbled in Rust, It&#x27;s always good to see the thoughts of someone who has spent a fair amount of time with the language who can give it a fair assessment.
herodotus大约 6 年前
&gt; Way Cooler is a Wayland compositor that was written in Rust using wlc<p>I know it is not easy, but I wish the author could have started with a paragraph that could help someone like me know whether or not the rest of the article would be something I would like to read.<p>How about something like this (and of course I may some of the facts wrong, but I want to be as constructive as I can):<p>&quot;Wayland is a Windows manager developed as a better alternative to X-Windows. Way Cooler is a tiling Wayland manager, written in Rust, and designed to be easily extendible. In this article I describe my experience in trying to refactor it, for reasons that will be described below. I will also explain why, in certain instances, C was a better choice for this project than Rust.&quot;
评论 #19779672 未加载
评论 #19779508 未加载
评论 #19780746 未加载
评论 #19780201 未加载
pcwalton大约 6 年前
I may be missing something, but what&#x27;s wrong with the first example? The fact that you can leak an object shouldn&#x27;t really matter for memory safety if it&#x27;s just a handle to an object that the server manages. Yeah, it could go <i>wrong</i>, but it won&#x27;t be <i>unsafe</i>. Object handles are essentially file descriptors, right?<p>In general I think there&#x27;s a tendency to overcomplicate safety features in Rust. The solution to an overly-complicated system isn&#x27;t to throw the whole notion of safety out the window: it&#x27;s to look at exactly what the complexity is buying you. If intricate combinations of Rust features are one extreme of the safety spectrum and C is the other extreme, there&#x27;s frequently a happy design medium somewhere in the middle.<p>Edit: Looks like oconnor663 over on Reddit had a similar but more specific proposal, which probably works: <a href="https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;biq864&#x2F;comment&#x2F;em2kipe" rel="nofollow">https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;rust&#x2F;comments&#x2F;biq864&#x2F;comment&#x2F;em2kip...</a>
评论 #19782164 未加载
mcguire大约 6 年前
&quot;<i>A Wayland “output” is the resource that represents a display device. Commonly this means it handles a computer monitor. This resource could disappear at any time in the life cycle of the application. This is easy enough to imagine: all it takes is a yank of the display’s power cord and the monitor goes away.</i> [Except it can&#x27;t; it can only disappear between callbacks?] <i>This is basically the exact opposite of the Rust memory model. Rust likes to own things and give compile-time defined borrows of that memory. This is runtime lifetime management that must be managed in some way.</i>&quot;<p>Something leads me to believe that there is something very wrong with the architecture of wlroots-rs. The output should be attached to a callback parameter or something, maybe? I don&#x27;t know enough about Wayland to say, but something ain&#x27;t right.
评论 #19779504 未加载
kccqzy大约 6 年前
This code<p><pre><code> fn some_wlroots_callback(output_handle: OutputHandle, surface_handle: SurfaceHandle) { output_handle.run(|output| { surface_handle.run(|surface| { &#x2F;&#x2F; maybe some more nested layers... }).unwrap() }).unwrap() } </code></pre> is just screaming continuation monad. You see the same code pattern in early Node.js code (sometimes leading to callback hell). In the JavaScript world, the problem was solved using Promises, and then async&#x2F;await syntax. But more fundamentally, this is an instance of the continuation monad at work.<p>The continuation monad transformer is defined as<p><pre><code> newtype ContT r m a = ContT { runContT :: (a -&gt; m r) -&gt; m r } </code></pre> and is nothing more than just a function that takes a callback. If this were Haskell, one could just write<p><pre><code> stuff = runContT $ do output &lt;- ContT (run outputHandle) surface &lt;- ContT (run surfaceHandle) -- and then maybe some more nested layers -- etc </code></pre> Granted, continuation code can easily be misused to produce an incomprehensible mess in Haskell (its full generality can be compared with goto), but with Rust&#x27;s FnOnce trait, the scope for misuse is considerably reduced.
评论 #19780418 未加载
lucideer大约 6 年前
Question (for any more knowledgable readers here) from someone with a somewhat shallow understanding of the topics discussed:<p>Does this end up being primarily a negative reflection on the general structure of:<p>(a) Rust<p>(b) wl-roots<p>(c) Wayland<p>(d) all three<p>(e) none of the above, it&#x27;s merely the incidental reality of trying to write code that&#x27;s compatible&#x2F;usable across multiple language ecosystems and none of the 3 projects can do much to improve this situation.
评论 #19779032 未加载
评论 #19779255 未加载
评论 #19779297 未加载
评论 #19780858 未加载
simag大约 6 年前
Interesting post that show some current limitations of Rust, especially when not being able to control the design entirely.<p>Rust&#x27;s ownership system makes it harder to deal with the kind of dynamics wlroots exposes... It seems to me that the issue here is that there is no consensus (e.g library) on how Rust should deal with those issues, so if you want to just to provide bindings to a dynamic system you end up writing middle-ware that deals with that kind of dynamics in a Rust idiomatic fashion (taking advantage of ownership) instead of focusing on the task at hand. It somehow destroys Rust&#x27;s promise of productivity.<p>A Rust project of mine[1], in an early stage and currently paused, deals with those issues (probably in a way similar to the Handles described in the post) by providing Service smart pointers (i.e, Svc&lt;T&gt;) and a component-framework that helps deal with the dynamics of a service being unregistered (e.g, a monitor unplugged, or a dynamic library unloaded) ; that component framework helps you be sure that if your struct contains a Svc&lt;Foo&gt;, that service is still available when you&#x27;re called, or the component reaches an invalid state.<p>In general, it seems to be an area where Rust&#x27;s ecosystem is still very early and would benefit from more input (such as this post) and consensus.<p>Regarding the callback-hell issue, that &quot;dehandle&quot; macro looks very much like async&#x2F;await, and it looks like it could be implemented either in terms of async&#x2F;await (still unstable) or generators (even more unstable).<p>Hopefully similar projects will be more likely to succeed as Rust and its ecosystem mature.<p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;magnet&#x2F;socrates-rs" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;magnet&#x2F;socrates-rs</a>
4bpp大约 6 年前
How does Rust handle these problems in the context of file I&#x2F;O? I&#x27;m sure there is an axiomatically idiomatic (official) implementation of it as part of the language distribution, and at the same time file handles seem conceptually very similar to display handles and should have similar failure patterns (space can run out, a disk can fail, a plug-and-play disk can be yanked out at any time...).
评论 #19779577 未加载
newnewpdro大约 6 年前
I only skimmed the article, but the description of outputs and their asynchronous lifecycle making things complicated just made me think of what&#x27;s become known as the ECS pattern in game development.<p>Your outputs sound just like entities in a game. They come and go as they please, and you often have multiple references to them from myriad places since entities may interact with many parts of the game.<p>I suspect if you investigated the established techniques for implementing ECS-style games in rust, you might find some simpler and established solutions for your troubles.
josteink大约 6 年前
Personally I think Rust is a great language. That said it may not be great for everyone nor a great fit for every problem.<p>Sometimes trying and admitting failure is a perfectly rational and valid option.
Lowkeyloki大约 6 年前
Everything the author and the commentors here have said is completely legit. I&#x27;m not looking to start a war. And I completely acknowledge that what I&#x27;m about to say might be wrong as I haven&#x27;t seen the author&#x27;s code or the code of wlroots.<p>But I have to wonder if the design decisions of wlroots itself may be dubious. If it&#x27;s this hard to manage memory safely when you&#x27;re trying to wrap the API in a language that demands you&#x27;re kept accountable for memory safety....
ac130kz大约 6 年前
Does wlroots itself present good code quality or it is basically a horrible wrapper to support every Xorg use case?
评论 #19780029 未加载
vectorEQ大约 6 年前
good ol C :). Thanks for sharing these experiences. Happy to see some example of the places where rust still falls a little short &#x2F; is a bit too restrictive for system programming. a lot of people deny this, but there&#x27;s plenty of situations where you just want plain old C for it&#x27;s straightforwardness to implement your own design. if you want to do it the &#x27;rust&#x27; way, you find yourself restricted in all kinds of ways. if you can live with those restrictions it&#x27;s great, but sometimes you just get stuck. Good luck on the rebuild in C!
mempko大约 6 年前
I have had the view that safety is typically not the most important goal of a project (user satisfaction is). I have often said that safety can get in the way of writing software that is useful. It&#x27;s great to see a real-life case with Rust from someone who obviously tried very hard but ultimately had safety get in the way of writing the software they wanted. Hopefully, Rust will evolve to interface with the &quot;unsafe&quot; world in a more ergonomic way.
shmerl大约 6 年前
A pity wlroots itself isn&#x27;t written in Rust.
评论 #19780023 未加载
scoutt大约 6 年前
&gt; When the benefit at the end of the day is just so I don’t have to write C, that doesn’t really make it worth it.<p>This line not only summarizes the content of the article, but I&#x27;m afraid it may also describe the actual situation of porting C&#x2F;C++ code to Rust.