Announcement

Collapse
No announcement yet.

Cloudflare Ditches Nginx For In-House, Rust-Written Pingora

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #71
    Originally posted by mdedetrich View Post
    There is no way to answer your question on a forum because its too big of an answer, but in general your comment only really make sense with really trivial/small code and completely falls apart when you are actually working on an actual codebase with thousands/hundreds/millions of lines of code and this is where safety guarantees around concurrency really start paying off since the number of interactions in your codebase typically scales exponentially the larger your code base is. Especially when you start implementing real concurrency/multithreading in your program, the problems with concurrency/multithreading really propagate to the rest of your program which is why a lot of C programmers either avoid multithreading or only use it for real low hanging fruit. One reason why a lot of the Rust equivalents are beating C programs is because the Rust programs take advantage of concurrency much more in C, and this is a lot easier in Rust.

    To drive this point further you also have to understand the context, Rust was created in Mozilla precisely because of how unproductive/inefficient/difficult it was to deal with these concurrency/memory problems on what is arguably one of the largest open source C/C++ codebases , aside from the Linux kernel, Firefox. Its not even due to size why Firefox is complex, its also a web browser which arguably aside from game engines or operating systems is one of the hardest types of programs to make.

    EDIT: Fun fact, one strong argument for why functional/purely functional programming started getting much more popular over time (in contrast to C imperative style) is that when you start implementing concurrency in your program, due to how it interacts with the rest of the program a lot of the abstractions/idioms in C style imperative programming fall apart for one reason or another, i.e. relying some form of global state which is typically implicit in a lot of C programs suddenly doesn't work so nicely because you know have to deal with multiple threads accessing that same state at once.
    This is exactly the kind of thing I wanted to avoid. Pure generic wall of text without giving a concrete simple example.

    I'm not asking for an actual example of actual production code, just something to illustrate an example of such problem that can appear in production code. It can be short and that's actually preferable, I just want to know WHAT exactly.

    Also, Mozilla's C++ code is horrible and full of hacks and stupid stuff. Comparing it to Rust is pointless since it's a lot worse than most C++ code I read. It's also full of macros, so you can imagine how horrible that is.

    Again, I'm not bashing the "return address of stack variable" because of the simple examples. Simple examples are perfectly fine. I'm bashing what they represent, which is, returning address of stack variable. That's what's beyond dumb. A mistake that you can only make while drunk. And anyway it's so trivial because any compiler will warn about it. Not sure why Rust proponents keep bringing it up.

    How does Rust handle concurrency better than C++ with RAII/smart pointers/etc? Simple example please. And I hope it's not about its standard library, because I want core language examples. Standard library can be replaced with better APIs or libraries, so that's not a good point to make. You don't need an entirely new language for that.

    Comment


    • #72
      Originally posted by Weasel View Post
      This is exactly the kind of thing I wanted to avoid. Pure generic wall of text without giving a concrete simple example.
      Your question cannot be answered in a concrete simple example which is why I am not providing it.

      Comment


      • #73
        Originally posted by piotrj3 View Post

        I mostly agree but not totally. For example if language is perfect for heavy majority of use cases you are about to implement but there is one architectural point not compatible with it, that doesn't mean you should abandon that language. For example mentioned Rust doesn't have inheritance and doesn't have exceptions but those issues are resolvable.

        Rust also is important here performance wise because design Cloudflare did is very hard to implement secure way in languages in C. You need language that has certain security guarantees with as big performance as possible. Fact you can do something in C doesn't mean it will be secure, and languages with similar security guarantees like Go are slower. When you have all threads accessing same connection it is very hard to make it in C securly. Rust design patterns allow you to do that with much less pain.
        You are right but my point here was that on enterprise you don't do those choices on the driver's seat like on smaller business/teams do but you receive a draft design that already have green light from high level suits/architecture teams and legal departments.

        that means using your own examples.

        1.) Best case scenario: an existent tool fit the design parameters, your team have know how of that tool and it offer extra features to make your life easier. In this case Rust directly as is.

        2.) Common scenario: several tools meet your design parameters partially, so get a team together and implement the missing bits. In this case implement memory borrow on C or implement inheritance on Rust.

        3.) Worst case scenario: you need to use Go because the top suits have an awesome SLA with Google that they love and most of your internal teams already are familiar with it, so call google, get a team together and find a way to met the performance criteria expected of the final product and contact legal for any extra steps.(you know stuff like FOSS the improvements or not, include that code under your SLA, etc. ).

        4.) Common Worst case scenario: You asked for Rust, you received a suit email stating the company policy that only allow C++(version X or Y) and the PDF with the internal coding guidelines (that is the first and last response you are going to get), even if you are high enough on the ladder to actually fight it off you have to find a way to convince the suits it is worth it enough to ditch all those millions of dollars you have on existing code, training, internal purview procedures, tools, SLA, licences, etc. Then you have to wait for legal god knows how long to determine if it comply with the internal normative and so on and on.

        On the enterprise design a software based on the features of a language is like a government designing a city based on the concrete chemical attributes because like on government enterprises have huge bureaucracy and invested interests and most decisions come from top to down and take into account every possible parameter except the damn language that will be used in the future to implement it.

        Comment


        • #74
          So basically mozilla created rust because they were too stupid to use c++ properly and refactor it. Take a look at how shit brave is with old mozilla devs. Majority of mozillas code was probably before constexpr, smartptr etc. So i get their need for a better language features in the past. But now with c++ standards getting its shit together this is such a none argument.

          Comment


          • #75
            Originally posted by Weasel View Post
            This is exactly the kind of thing I wanted to avoid. Pure generic wall of text without giving a concrete simple example.

            I'm not asking for an actual example of actual production code, just something to illustrate an example of such problem that can appear in production code. It can be short and that's actually preferable, I just want to know WHAT exactly.

            Also, Mozilla's C++ code is horrible and full of hacks and stupid stuff. Comparing it to Rust is pointless since it's a lot worse than most C++ code I read. It's also full of macros, so you can imagine how horrible that is.

            Again, I'm not bashing the "return address of stack variable" because of the simple examples. Simple examples are perfectly fine. I'm bashing what they represent, which is, returning address of stack variable. That's what's beyond dumb. A mistake that you can only make while drunk. And anyway it's so trivial because any compiler will warn about it. Not sure why Rust proponents keep bringing it up.

            How does Rust handle concurrency better than C++ with RAII/smart pointers/etc? Simple example please. And I hope it's not about its standard library, because I want core language examples. Standard library can be replaced with better APIs or libraries, so that's not a good point to make. You don't need an entirely new language for that.
            I don't think you understand the issue. Any big C++ has tons of hacks. So does C. I seen hacks in MPV, firefox, chromium, etc codebases. Linux, BSD and much more have a lot of goto (for good reason but still). Valve open sourced stuff also have funny programmer comments "this is a stupid fix", "this seems like bad idea but it is fine for now" etc. etc.

            And yes Rust handle concurrency better then C++ because smart pointers of C++ are runtime based. Rust system is compile time based. What basicly means Rust in that case not only is faster, but also can give you guarantee before program even runs. This is something that Cloudflare, discord, NPM developers, or even Karol Herbst (that recently wrote openCL driver in rust) mentioned - that they had to not deal with random memory bugs at all. Many of them also mentioned that cost of maintaining this software is low.

            Also Rust compiler information is really good, when C++ compiler errors are pure garbage.

            In case of Rust there is few checks that are not possible in C++ - in static memory bounds checking is done at compile time (you can easly go out of bounds in C++), in dynamic memory out-of-bounds checking is done in runtime.

            Of course errors for sake of errors are bad examples of real issue but...

            Code:
            std::vector<std::string> v;
            std::string str = "example";
            v.push_back(std::move(str)); // str is now valid but unspecified
            str[0]; // undefined behavior: operator[](size_t n) has a precondition size() > n​
            Rust won't allow you such thing. Entire large family of bugs like use-after-move, Iterator invalidation​, Null pointer dereference​, are still possible in c++ and modern C++ doesn't protect anyhow user against them. And those bugs still plague as CVEs even biggest and most modern C++ codebases.

            And most important issue, C++ concurency is in its infancy and it is not as far performance optimized as Async from Rust. Meanwhile typical Rust async runtime like Tokio is runned by.... a lot of big companies.
            Last edited by piotrj3; 18 September 2022, 08:45 PM.

            Comment


            • #76
              Originally posted by piotrj3 View Post

              I don't think you understand the issue. Any big C++ has tons of hacks. So does C. I seen hacks in MPV, firefox, chromium, etc codebases. Linux, BSD and much more have a lot of goto (for good reason but still). Valve open sourced stuff also have funny programmer comments "this is a stupid fix", "this seems like bad idea but it is fine for now" etc. etc.

              And yes Rust handle concurrency better then C++ because smart pointers of C++ are runtime based. Rust system is compile time based. What basicly means Rust in that case not only is faster, but also can give you guarantee before program even runs. This is something that Cloudflare, discord, NPM developers, or even Karol Herbst (that recently wrote openCL driver in rust) mentioned - that they had to not deal with random memory bugs at all. Many of them also mentioned that cost of maintaining this software is low.

              Also Rust compiler information is really good, when C++ compiler errors are pure garbage.

              In case of Rust there is few checks that are not possible in C++ - in static memory bounds checking is done at compile time (you can easly go out of bounds in C++), in dynamic memory out-of-bounds checking is done in runtime.

              Of course errors for sake of errors are bad examples of real issue but...

              Code:
              std::vector<std::string> v;
              std::string str = "example";
              v.push_back(std::move(str)); // str is now valid but unspecified
              str[0]; // undefined behavior: operator[](size_t n) has a precondition size() > n​
              Rust won't allow you such thing. Entire large family of bugs like use-after-move, Iterator invalidation​, Null pointer dereference​, are still possible in c++ and modern C++ doesn't protect anyhow user against them. And those bugs still plague as CVEs even biggest and most modern C++ codebases.

              And most important issue, C++ concurency is in its infancy and it is not as far performance optimized as Async from Rust. Meanwhile typical Rust async runtime like Tokio is runned by.... a lot of big companies.
              I agree and i think developers without strong electronics background should use Rust instead of C/C++ that being said those things you mentioned are necessary in many cases as long as you understand how the hardware will react without getting in your way. So right tool for the job

              Also concurrency is a very broad term that developers now days seem to relate to threads or processes or async, etc. or some combination of those but is more a design term and there is a myriad of variant you can use and still be considered concurrent but yeah as far as async goes tokio does a good job providing a full async pipeline while C++ async is more akin to a construct so they aren't really apples to apples comparable tho.

              Comment


              • #77
                Originally posted by Anux View Post
                You wanted to prove something, not me.
                Nope. You misread my statement.

                Originally posted by Anux View Post
                Damn who's paying you 110K? I should easily get 990K there.
                Nope again. People that misread statements like the above will not get a job here. Not even for cleaning the restrooms.

                Comment


                • #78
                  Originally posted by jrch2k8 View Post

                  In my experience it works backwards on business at least, first you get a team that will design the proper algorithmic flow/ design then you choose a set of language(s) from a pool based on cost(i don't mean money).

                  * by cost i mean SLA, available tooling, in-house expertise, documentation/training availability, platform support, future availability, etc. etc.

                  Your way is more for small teams and FOSS models but for business i'm not so sure. that been said i don't know the workflow on cloudfare and is not clear what process they used
                  My experience from development within large corporations is usually: "all our devs have java experience. Let's use java for this project so they already have the necessary know how and can re-use existing code". Often they don't even ask the devs. By the time more devs join the project, the code base is already prepared with the basics and the language is set in stone. When, as an architect, I tried to convince the project leads to use a different technology it almost always ended with "no, we don't have that know how". Which was bullshit - I talked with enough other devs to know, that they a) had interest in finally doing something else and b) enough of them already played around with other tech stacks as well. But in the end they had to keep doing the same shit they did for 15 years; no matter that they weren't that interested in that anymore or that it simply didn't fit the project requirements.

                  Comment


                  • #79
                    Originally posted by mdedetrich View Post
                    Your question cannot be answered in a concrete simple example which is why I am not providing it.
                    You don't have to write it yourself. You can just link to an article describing it? Like literally, is there NOTHING out there?

                    The point is I did try to search and I always get stupid examples where no proper C++ programmer would make such mistake, or he would be using RAII/smart pointers. I can give you links if you want, just to prove it to you, but I hope that's not needed.

                    Comment


                    • #80
                      Originally posted by Weasel View Post
                      where no proper C++ programmer would make such mistake, or he would be using RAII/smart pointers.
                      That is the typical "real programmers" fallacy. The problem is that there are no "proper C programmers" out there or atleast not enough.

                      Comment

                      Working...
                      X