Async Rust Is A Bad Language | Prime Reacts

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
async rust is a bad language but to get at whatever the hell I mean by that we need to talk about why asynchrust exists in the first place let's talk about it okay this is great I love this I already love this starting off the conversation giving us the proper context let's go modern concurrency they're green they're mean and they ate my machine I don't get it and that guy's face doesn't look like he wants to be here either suppose we want our code to go fast we have two big problems to solve we want to use the whole computer code runs on CPUs and in 2023 even my phone has eight of the damn things I got a new phone by the way look at this sweet pixel 7. it's pretty neat I no longer have a bright line down the middle of my phone pretty cool huh if I want to use more than 12 of my machine I need several cores this is true even in my some of my best attempts I still can't get node to use 100 of the CPU I've tried so hard to make it just use ass CPU and I cannot make it uh we want to keep uh working while we wait for slow things to complete instead of just twiddling our thumb sending a message over the Internet or even opening a file takes in eternities in computer time we could literally do millions of other things meanwhile very fair and so on we turn our friends parallelism and concurrency it's the favorite hobby of Cs nerds to quibble over distinctions between the two so to oversimplify parallelism is about running code in parallel on several CPUs concurrency is about breaking a problem into separate independent parts I'll give my my take on it which is parallelism is having machine instructions executed simultaneously concurrency is having tasks that do not need CPU to move out of the way and allow other tasks to run while it's waiting for a result concurrent my nuts out your mouth okay I don't know how I got that one but that's about fair was that a is that about a fair-ish statement wrong again parallel is is more than one thing happening at once whereas concurrency is is stacking them like bricks parallelism is a subset of concurrency I don't believe that parallel is at the exact same time occurring at the same time interval okay that somehow makes it less clear now I think everybody's more confused at this point I'm still confused what's the difference okay think of no think of node.js when you do a uh think of this right here here we go this guy this code okay not that code Vim test this right here right one is going to take one second two is going to take two seconds we can either run them one at a time this is not concurrent or parallel or run them both at the same time but here's the deal one will run until it relieves any need of the CPU then two will run and relieve any need of the CPU and then one will pick back up after it's one second wait and then start running and then be done and then two will pick up after two seconds and pick it up this will take a grand total of two seconds it's concurrent but it's not parallel one is not executing at the same time two is that's concurrency concurrent processes overlap parallel runs literally the same time that's why it was specific there's at least two lines of running machine code like something is happening two different because you can you can have parallelism and they're not running the same code they don't have I don't think there's any requirement that it has to be identical code being ran uh they could be running different parts chipboard politics yeah okay whatever I think we all get it we're moving on these are not the same thing single core machines have been running code concurrently for a half century now but they are related so much online well actually well actually ignore dude we literally just did this we literally just did this we're doing this okay right now um ignores how often we break programs into concurrent pieces so that those pieces can run in parallel and interleave in ways keep our cores crunching we didn't care about performance why would we bother so let's see how do I concurrency one of the simplest ways to build a concurrent system is to split the code into multiple processes after all the operating system is lean mean concurrency machine conspiring uh with your Hardware to make each process think it has its whole box to itself the OS scheduler gives us parallelism for uh free running time slices of any process that's already on on an available CPU core Once Upon a Time this was the way and we simply we still employ it today whenever we pipe shell commands together let's talk about golf build tool oh no a lot of you javascripters are discovering that it is a lot more efficient to pass data from task to task rather than writing it to disk between each step or akka actors in Scala concurrency sure is simpler with non-shared memory and immutable messages huh okay let's begin with processing pipes they've been in Unix for 40 goddamn years this is actually really funny by the way this is this is really good uh it's been happening forever but this approach has limitations inter-process communication is not cheap since most implementations copy data to OS memory and back yep uh mutex based concurrency considered harmful or horror was right uh some people when confronted with a problem think I know I'll use threads and then they have two awesome this is such a good statement this is a beautiful statement right this is a beautiful statement okay this is parallelism getting awful we can avoid these overheads using threads processes that share the same memory uh common wisdom teaches us to connect them with mysterious beasts like mutexes and conditional variables and semaphores isn't a semaphore just a mutex with a wider Lane just has a higher count to begin with um anyways yeah I know I'm just saying I'm just saying that just okay anyways uh this is a dangerous game I mean I like using this I have my little test clients all use this I think it's a lot of fun to use semaphores to produce asynchronous code it's fun I I mean I actually enjoy it a little Tokyo spawn a little semaphore a little glass of wine and you got yourself a seg phone uh This Is A Dangerous Game simply uh simple mistakes will plague you with the race conditions and Deadlocks and other terrible diseases that fill your code with bugs but only on Tuesdays when it's raining and the temperature is in the middle of three is a multiple of three oh gosh it's a red riddle and God help you if you want to learn how this stuff actually works on Modern Hardware Fair all those are fair statements all of it fair statements there's another way in this 1978 paper communicating sequential processes Tony horror suggests Connecting Threads with cues or channels which they can use to send each other messages this has many advantages are we just slowly becoming go is this literally a statement of like hey man you want to hear about go I think this is where we're going or erlang okay erling sorry it's erlang uh dude erlings is literally The Simpsons of programming oh is this goat erlang did it okay it showed up threads and joy process like isolation from the rest sorry the music was a little loud uh threads enjoy process like isolation from the rest of the program since they don't share memory bonus points for memory safe languages that make it hard to accidentally scramble another thread yeah rust uh each thread has very obvious set of inputs the channels it receives from and the outputs the channel it sends to this is a re this is easy to reason about and is easy to bug it's actually true it is very easy to debug these type of problems instrument uh the channels for powerful visibility into your system measuring each thread's throughput channels are the synchronization if a channel is empty the receiver Waits until it's not if a channel is full the sender Waits yeah this is actually I mean this is beautiful threads never sleep while they have work to do graceful pausing if they outpace the rest of the system okay after Decades of mutex Madness many many modern languages heed advice and provide channels in their standard library in Rust we call them sync Channel okay most software can stop here building concurrent systems with threads and channels combine them with tools to parallelize CPU intensive Loops like Russ rayon or Haskell's par ooh Haskell mentioned can we get a w Haskell mention pick pick come on down pick dude anytime Haskell gets mentioned there's just high fives like 35 individual people just start high-fiving each other and they're just like yeah they recognized us let's go pick sitting there at the leaders full on full-on cult Enthusiast oh it's so good uh and you've got a powerful cocktail I do think that I've relied too heavily on async await and maybe I do need to consider more just playing with this kind of stuff but Ludicrous Speed go some problems demand a lot of concurrency the canonical example described by uh Dan Cagle did I say his name right the man's name is Kegel did he invent anything else is there any other well-known item that uh this damn fella happened to to know about I'm doing one right now that squeeze was great uh as the C 10K problem back in 1999 is a web server connected to tens of thousands of concurrent users at this scale threads won't cut it uh while they are pretty cheap fire up a thread per connection and your computer will grind to a halt to solve this some language provide a concurrency model where tasks are cheap and managed by uh in user space I.E without operating systems help a runtime schedule these tasks onto a pool of os threads usually size so each CPU core gets a thread to Max maximize parallel parallelism very hard word by the way to say rust calls this the MN thread problem okay uh this scheme goes by many names green threads lightweight threads lightweight processes fibers co-routines did you know that in react they also use the term fiber starting in react 16. um as somebody who's been recently going through their source code and reading a lot of lines of it just saying okay that that it exists and react as well uh and more complete and with pedantic nerds endlessly debating the subtle differences between them Russ comes in with this problem with async await model seen previously in places like c-sharp and node.js here functions are marked async don't block you but immediately return a future or promise that can be awaited to produce the result a little different though than node.js in node.js World an async function is greedy it runs right away it's hot is another term for it whereas with uh rust unless if you call Dot await it doesn't ever actually run which can bite some serious ass okay you may not realize that I've heard the term cold be that used lazy you know there's a lot of terms for it Foo returns an end async food returns a future that we cannot await to get it weight I've been here before you should have thrown a literally should have thrown a little Arc mutex somewhere in here uh on one hand Futures in Rust are exceedingly small and fast thanks to their Cooperative schedules stackless design but unlike other languages with user space concurrency rust tries to offer this abstraction while also promising the programmer total low-level control there's a fundamental tension between the two and the poor async rust programmer is perpetually caught in the middle Torn Between the language's design goals and the massively concurrent World they are trying to build rust attempts to uh statically statically verify the lifetime of every object in reference in your program I still truly don't understand pin and unpin okay I keep trying okay I haven't tried in a little while I'm just saying that sometimes you gotta pin it sometimes you want to not unpin it sometimes you want to unpin it okay sometimes you want an async reader plus unpin I know that's almost like pin doesn't move you're like oh okay that makes perfect sense okay I get it now I get it I super cool um design goal is a massively concurrent world they're trying to build rust attempts to statically verify the lifetime of every object in reference in your program at compile time Futures promise the opposite that we can break code and the data it references into thousands of little pieces runnable at any time on any thread based on on conditions we can only know once we've started a future that reads data from a client should only run when that client's socket has data to read and no lifetime annotation will tell us when that might be it's actually a really fair take so that's why send you asked about say this sounds like a send problem uh assuring the compiler will uh shortly probably that everything will be okay runs into the same challenges you see when working with raw threads just raw dog those threads data must either be marked Ascend or moved or pass through references with a static lifetime both are easier said than done moving at least without cloning is often a non-starter dude it's so annoying this is like the this part is such an emotional bruising moment do you know what I mean like this is such an emotionally bruising moment when you start getting into this oh my goodness since it's common in async code to spawn many tasks that share common state the reference uh references are a pain too there there's no thread scope equivalent to help us bound future lifetimes to anything short of forever I thought there was some level I thought in uh Mara Mara's Book on a uh threat atomics or uh rust atomics there was some sort of thread scoping that allowed some version of this I could be wrong though it could be very very wrong uh Foo big chungus get that big chunk is out here async food big Global static ref or something similar horror chungus sendable chungus clone that's pretty good you gotta have that sendable clonable chungus okay it's a requirement unlike launching raw threads where you might have to deal with these annoyances in a handful of functions this happens constantly due to async's viral nature yep since any function that calls async function must itself be async so I talked about this earlier this is the problem of a leaky abstraction when you have one thing that uses something the thing that uses it must also become it itself and so you just like all the way back or you create a something that can walk a future in Rust which I'm still not quite sure of how that works uh you need to solve this problem everywhere all the time just Arc my up toss a little mutex on there a seasoned rust developer will respond by saying that Russ gives us a simple toe of our Dynamic lifetime spanning multiple threads we call them Atomic reference counts as or Arc for short did I do a good recipe um while while it's true dude so Republican versus Democrat functions yes this is what we're talking about while it's true that they solve the immediate problem borrow check and our code compiles they are far from the Silver Bullet used pervasively Arc gives you the world's worst garbage collector like the GC the lifetime of an object and the resources they represent memory file sockets is unknowable but you can take this loss without the wins you'd get from actual GC it's true you get all the inconveniences of rust with none of the benefits of GC that's pretty good don't buy the GCS slow fun yeah I think that like Discord probably did the largest disservice ever to the GC is slow and bad they're like on an old version of go they had no tuning that was being done there's a lot of improvements in go and what they've been doing with with that and I really hope memory Arena's come out but it's true don't buy the GCS slow fun GCS can be fast you can make things good in a compiled language with the GC it is possible gochi see is a great it's a great GC the claim is misunderstanding of a latency versus throughput at the best and bizarre psyop at worst throughput at best and a bizarre psyop at worst I love a good psyop I am all in on a good psyop a modern moving garbage collector gets you more allocation throughput less fragmentation and means you don't have to play Mickey Mouse games when weak pointers to avoid cycle leaks yep and you can even trick the system programmers into leveraging GC in one of the world's most important software projects by calling it deferred destruction colonel.org someone stuck in a GC someone stuck in a little deferred destruction step B the above key to underlying rco's deferred destruction HR here uh hold up please that's actually pretty funny uh another random nonsense let's say other random nonsense I'm not sure if that's actually real or what they're saying if it's really a garbage collector or anything but it's just a funny idea that that exists because rusco routines our stackless the compiler turns each one of them into a state machine that advances to the next await yeah if you've ever looked at some of the code that is generated it's pretty wild but this makes any recursive async function a recursively defined type a user just trying to call a function from itself is met with inscrutable errors until they manually box it or use a crate that does the same well I've never tried a async recursive function huh there's an important distinction between a future what does nothing until awaited in a task which spawns work in the runtime's thread pool returning a future that marks its completion exactly this is true I mentioned this earlier uh there's nothing keeping you from calling blocking code inside a future and there's nothing keeping that call from blocking the runtime's thread it's on also true you know the entire thing we're trying to avoid with async I mean I've done this a lot of times with rust I did this a lot of times with rust it can be quite tricky running away always Monty Python's always a solid reference what is your favorite color um mixed together this gives you async rust a much different flavor than a normal rust oh one with many gotchas that are harder to understand and teach and pushes users either to develop a deep understanding of how abstractions actually work writing complicated code to handle them or sprinkling Arc pin static unpin pin project some structures with also a pin macro somehow sprinkled on them um you know in other sacred runes throughout their code base uh and hope for the best this is me I'm pretty much on this team I'm on team Arc mutex you know I'll take option two the thing is is that you gotta remember that when they say this what they what they mean is that it's not something like you know like don't worry about that you know like the difference between going from geez uh like I don't understand the Dom because I don't get trees is like it's a small Gap right like we can all agree that that Gap looks something like this right it's a small little Gap right you have to learn a little bit and then you kind of get it and you're like okay I understand how you recursively descend I understand breath first versus depth first search okay I get this whereas I added an a at the end of it whereas when it comes to rust async it's like the amount of stuff you do have to learn you have to actually learn what pin pin is actually doing you have to oopsies uh you have to learn about like what is actually happening with the rust run time and how async is handled what the hell is happening what are all these extra things that are going on why do you have to mark some of these structures as some sort of pin project like it just keeps ongoing right it just keeps on happening and keeps getting thicker and thicker and thicker it takes a while to get over it you know what I mean it just does all right uh rust proponents I'd consider myself one might call these criticisms overblown but I've seen whole teams of experienced developers trying to use rust for some new project mired in this minutia to whatever challenges teaching rust has async adds a whole new set agreed cries nasync is a real meme because it really exists right it really really exists rust is like a learning pointers and mallex all over again yeah but it's eat like honestly just rust it's pretty simple right like I genuinely just rust a little CLI that does something it's pretty straightforward but the moment you get into these like some of the more Arcane sides of rust the difficulty is just like a serious step function harder right you're not learning you're learning both a concept and how to express it in rust's kind of constricted language and how they do things sink rust a day async rust that uh to a degree to which these problems aren't just a thing in other languages can't be overstated in Haskell or go async code is normal code you might say this isn't a fair comparison after all those languages hide differences between blocking and non-blocking code behind a fat runtime and lifetimes are hand waved with garbage collection but that's exactly the point these are pure wins they are doing with this sort of programming it's true it's very true maybe rust isn't a good tool for massively concurrent user space software uh we can save it for the 99 of our projects that don't have to be I love rust when doing CLI tools I love rust for CLI tools so yeah I agree with this I like I genuinely agree with that statement one a file which could be on the other side of the Internet thanks uh NFS I'm not sure what that is um until we could cut down IPC overhead by sharing memory between processes but uh but this gives us but this gives away one of the main advantages of multiple processes the OS isolated from each other yep I like that Mara boss recently put out a fantastic book that despite targeting Russ specifically does a wonderful job explaining the fundamentals of low-level concurrency in any language uh yeah I I've read I've read through most the books pretty good like it's pretty good book if you don't have time to for the whole book I've done my best to sum it up in a few pages also super cool of course I'm simplifying here not every programmer can express uh not every program could be expressed as a dag Fair you'll find good occasions for other Primitives say Atomic Flags to indicate changes in global State still horse model is great default and I've always found it helpful to think about how data flows through my system each thread has four kilobyte control block and Linux and switching between threads require a trip to the operating system scheduler this context switch to the OS memory is much more expensive than a normal function call Fair uh uniquely rust doesn't provide a runtime for its Futures in the language delegating instead to libraries like Tokyo this is great for users rust builds tool cargo and ecosystem gives developers freedom to choose Alternatives that are better suit unique environments they find themselves in that's that's true that's true I mean it sucks that people like Tokyo also have to shoulder the community for most concurrency Tokyo right like I I do think that that is the sucky downside of this is that people who develop these alternatives are truly like that's a pretty tough job to have but it's a detail that largely immaterial to our discussion one that can imagine a world where Tokyo is built into another language and all the same rules apply you can break a chain by commanding the entire runtime to uh block on this is true and I've done it many times on a completion of a future you probably shouldn't do this pervasively since it isn't composable if a function blocks on a future and that future calls a function that blocks on the future congrats runtime panics um facts eight uh learn more in without boats future and segmented stacks and the C plus plus paper okay cool Amos Wagner AKA fast and limes pin and suffering is a fantastic snarky intro there you go now you see it all I actually agree with this I think that uh my Ventures into async rust though I built several programs that I'm happy about and I've done well um and I'm very very happy that I did some using a bunch of async awaits I'm not in fact like if you look at this little shooter game My Little oopsies uh I just did the wrong thing there um I just what is happening my brain just just totally went to twice I used a bunch of like I used semaphores to kind of do this and do some nice little fun things right here and join a couple little items right here enjoyed it very very much doing this kind of stuff I I I I have actually enjoyed these kind of things and I think it's really fun to use semaphores and all that but ultimately at the end of the day I'm still relying on the async nature of it and I do a bunch of box leakings for that exact same reason I just need a static reference right I just need a reference out that I can just have everybody else uh using this article screams uh skill issue so I don't my big problem with this is that I don't believe that you know what I mean because here's the problem with that statement in general and and one of the reasons why I I semi-dislike the phrase skill issue is that some are just genuine skill issues but some the requirement to be good at async rust not just like kind of good right you could build a simple web server that cruds out stuff that does stuff not hard async we could all do that super simple throw up a turso client hit the database really easily by the way Tercel is doing something incredible that I'll be talking about here soon that involves a millisecond transactions or a micro second transactions it's incredible um but nonetheless it's like that's simple simple async is simple in Rust large async uh large async programs become very hard in Rust and can become very hard and rust and so I really don't think that um I don't think this article is far off I think that's why again I just really really love uh and the thing is is that when you have to do something like if you're going to get a group of people to try to learn async rust to the fullest extent you're asking them to learn rust to an exceptionally deep level that's like do you just want to be a rust only Andy or are you someone that's more like I'm truly trying to be someone that works on many stacks of any kind and so that's kind of the thing you have to choose to do and I'm not saying it's bad I like rust but I like to go and I also like typescript and I also don't mind working in just JavaScript with JS Doc and I also don't mind working in Lua and when I have to I've done that one big gigantic multi-threaded objective-c program that was pretty terrible because I hate Objective C I'll even work in a C plus plus I'd love to get into oh camel right and so it's like for me it's like I'm fine kind of being in a bunch of places you know what I mean I'm fine doing a bunch of stuff but it also means I can't go super deep to the level of understanding rust async at a compiler level because that would just be really hard but I could get there I mean theoretically I could just take that amount of time and and do it I like TS yeah TS is just fine TS here's the deal typescript takes a shitty language and makes it slightly less shitty anyways I don't mind typescript I just think it's still a shitty language it still has shitty things and I think large typescript programs are bound to be incredibly emotional right that no matter how much you want it to be good it is a it is an act of refactoring types and logic that is very annoying um so that's that small programs I really am fine using typescript you know if I just need to get something really quick I'll just use that sometimes that'll rust I tend to use rust or typescript for a quick CLI app depending on how I'm running it now that I have bun I'll probably use typescript more frequently for something easy so just thoughts but I like this I like this take I actually really like this take great job bit bashing sweet article that was a sweet article typically whenever I do anything to with the CLI I I I actually uh pick um rust instead of a node because I want to write typescript but I don't want to build a build system and uh TS TS node or any of these other Runners are just really annoying to set up and then setting up everything is also super annoying to set up so I just tend to not ever use that but now that Bun's there maybe I could see myself using it but there's still a lot more that I'll have to think about you know what I mean a TS node hurts it does it's an emotional pain and then you got like this TS paths issue and it just every single time I get super pissed off at it you know what I mean I get just super pissed yeah Dino maybe I do need to invest a little bit more into Dino yeah I agree I I fully I by the way I'm fully angry and so Striker I actually I have a video dropping here maybe next week on bun and my real impressions of bun it is not production ready one is a lie the name is the asyncogen
Info
Channel: ThePrimeTime
Views: 90,152
Rating: undefined out of 5
Keywords: programming, computer, software, software engineer, software engineering, program, development, developing, developer, developers, web design, web developer, web development, programmer humor, humor, memes, software memes, engineer, engineering, Regex, regexs, regexes, netflix, vscode, vscode engineer, vscode plugins, Lenovo, customer service
Id: ANu2TDkKotw
Channel Id: undefined
Length: 28min 45sec (1725 seconds)
Published: Mon Sep 25 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.