called kikei-kalka-kikei-kalka-kikei. Say that 25 times fast. Good? Called Kikei-kalka-kalka-kikei-kalka-kikei-kalka-kikei-kalka-kikei-kalka-kikei-kalka-kikei-kalka-kikei-kalka-kikei-kalka-kikei-kalka-kikei.  I got a C and a K, I'm Rick- Please follow us on Instagram and Twitter. We are called Juicy Content. It's so juicy. And... Angkor Sosa on Patreon, a Polish official Twitter account. And today we are doing something different, but I'm assuming this is Kalki. It is with Kalki Kekla. Kalki Kekla, which still doesn't make any sense to me, but that's how you pronounce it.  That's your name. It's your name. So Kalki Kekla, this is called the printing machine. It's from Unblushed. She does a series, she's done a few of these actually. It's poetry, it's a poetry video. Okay. I think her poetry? Yes, I believe it's her poetry and she speaks it and it's her in the video. So she does this like, is this like a YouTube channel thing of hers or a web series thing of hers? She's doing a, it's Blush YouTube series. Okay, so Blush is the channel. But it's her, and she contributed to it and this is her poem called the printing machine. Here we go.  Sharing headlines that make you gluck, gluck your drink. Sharing primes against women. Steep rising ink. Gambling Japanese tourists. International sting, sting. Strip switch for menstruating. Blink, blink. Ear on foresail from starving. Think, think. Gile breaks by politician. Garching, garching. Chir, dah, dah, dah, dah, dah, dah, dah, dah, dah. Treatment of machine harps happening in your drink to ink that makes us thunks sink and teaches us to fear everything. Fear the beast, writing the nights from deli to quantity. Can't call it wow, growling, growl, growl, growling. Beast of poverty, beast on a shopping spree. Midnight Cinderella. 10 o'clock to dirty fella. Oh hell, it really doesn't matter. It was afternoon in the warehouse and nobody heard her. It was just growl, growl, growling, going louder and louder. The machine chur, chur, churring faster and faster. Churring a nation of pride itself and hanging of four men.  Chur, chur, churring, a village dangling of two girls and up dolls upon a tree. Chur, dah, dah, dah, dah, dah, dah, dah, dah. Tree goes the fizzy printing machine till heads pile up in our hands and a crisp and clean on our newspaper stand and blend smoothly into our morning routine. Heads for one side or another, like a black and white marketplace. Two heads for four, four heads more, eight heads for a martyr, enough heads to start a war. I mean, how many heads are we after? Churring one after another. Dah, dah, dah, dah, dah, dah, dah. And when you think it's over, when the machine stops with a sudden, dah, dah, dah, dah, dah, dah, dah, dah, dah, dah, dah, tree, wait a little, wait patiently. It's just ready in dah, dah, to chur, dah, dah, at textbooks, dah, dah, dah, dah, dah, rewritten histories of dissected countries of majorities and popular beliefs and then the long, slow chur. In italics and roman prints of sweeping statements made by official establishments to take safety precautions and make improvements based on political views and religious sentiments. Churring out the box of sin, got out of the clothes room, the men would win their sins, the color of their skins, speaking of which, cheering horizontal lines vertically to paint the tree. In soft baby paint, the pleasant, bold, blue page revealing a fair and lovely face which melts a few pages on with the rise of acid sand, chur, dah, dah, dah, dah, dah, dah, dah, dah, dah, tree, the machine sinks obliviously. Churring magazines with shiny sheens to accommodate set-up socially subduing a world we can buy into, a dream we can hand on to, a love that defies one way to two, values that depend on what others think of you and you know that you are what you say and not what you do. So keep tap, tap, tapping on the keyboards, computing virtual drawing rooms that communicate it. Tap, tap, tweak, tap, tap, smooth, tap, tap, texting, tap, tap, emoticoning whilst our machine gives chur. Da, da, da, da, da, da, da, da, da, da, da, tree, the family and Mary has nothing to do. Chur, da, da, da, da, da, da, da, da, true with a manual. Chur, da, da, da, da, da, da, da, da, draw to underwear and bra. Babies count fights seriously in luxury. So hurrah, hurrah, let's drill her a bikini every time she raises her head to climb it. You see, God forbids multiplicity for a woman in our society. Chur, da, da, it goes up precious for the machine. Churring in amounts for nakedness by wearing less than half. Churring bitterness in mothers that feel better than in sleeping in the future.  Quiet revenge of the weaker steps from behind the guise of a tasting plant. Tap, tap, tap, tap, tap, like an option. Churring new breaths that grow into man. Churring little ladies that use hearts to pretend they manipulate. And defend themselves from the grove, grove, grove, beasts of doubt and survival for better theories until their whole existence becomes just a little series.  They're all an irony of all irons. They're one they reveal how our great and new heritage held to its feet.  The girl's talented. Girl's an artist. And I knew that before this. I mean, you could tell. Oh, yeah. If you pay attention to Kalki at all, you recognize that she's at her core, she's an artist. She's a creative person. And obviously very passionate about women's rights around the world and India. 100%. And obviously a lot of these are relatable to women anywhere in the world. Anywhere. It's universal. So like what she was saying about, I mean, there was a lot of stuff she said in there, but the beginning parts where she was talking about in the magazines that we learn as little girls to look up to certain images and then fear if we don't become those images. And then obviously a lot of the stuff with women having to suppress whatever they feel because it's a man's world and all this kind of. Yeah. And how the images feed in young boys and men, those images feed expectations that they have of women as well as feed the sinister aspect of the male psyche that thinks a woman is there is just to be a life support system for a vagina.  And the thing about this that I think is so, so good, I didn't expect what I really kind of was expecting a spoken word kind of thing with a mic. I didn't expect there to be an accompanying musical part or a visual part that we're both captivating. So there's multiple, there's multiple aspects to this that I would love to see this just as a written form with nothing but the word to really ingest what she's saying. Cause there were some times in there that all that was important for you to know in that moment was what she was saying poetically in the line. But then the musicality of it was extremely creative and brilliant. And the visuals for the video were very artistic and accompanying strong. And like most things we see like this, on the one hand, I'm thrilled to see this kind of a message being stated and said in an artistic way. On the other hand, I'm so disappointed to know that so few people will not only not see it, so few people will see it and not understand what she's saying. Oh yeah. Sadly, like the people that need to hear this kind of thing can't understand this. Exactly. It's seeing they won't see, hearing they won't hear. I'm hoping they will, but people that think these certain ways don't have a lot of brain capacity. Yes sadly, sadly what would happen is the men that need to hear this kind of a thing would watch this and what they would be looking at as well. Kalki looks really good in that dress. Yeah. Or they'll go and do the what about is. And they'll be like, yeah, but men also have discriminated. Yeah. And the other thing I was thinking as well, and some of you may comment on this because some people may watch this and go, yeah Kalki be careful you don't bite the hand that feeds you because she is at a place with her stature and her notoriety and her celebrity and her career where she does photo shoots where she does do things that are within the system she is saying you need to be careful of. Yeah. I don't think she cares. No, she shouldn't. And because I know there's other stuff of hers that she's done with other company and she does, she has a couple of these poems. I don't know if they're all about this, but I know she has an AIB video that we obviously haven't watched yet, but it's called AIB Rape Is Your Fault. And it's her. But it's AIB. So it's probably done in a sapphire way. Right, right, right. Obviously, because they don't do stuff like this. No, no, but obviously we haven't watched that one yet. But so I know she's very passionate about this type of stuff as, you know, she should be. Most people should be. And should be at a position where, I mean, that's part of the responsibility of an artist is that you're able to express yourself in artistic ways to express the importance of things that need to be changed in society. And a follower on Instagram, and if you watch and look at her posts, yeah, of course she does modeling shoots and things where she's endorsing products, but I've looked at her stuff. She in no way, shape or form contributes to anything that undermines the power and dignity of a woman. She just doesn't. And nor have we seen that in any of her work. In fact, it's the opposite. Yeah, it's all about. Power of a woman. Exactly. Women are obviously equal and there should be no differentiation between men and women. Yeah, and there shouldn't be, there really shouldn't be this pornographically sexualized imprint on a woman that's placed there by men and some women actually, they give in and cater to that, where a woman should be able to be herself and be beautiful and be sexy without becoming objectified by a man.  It's never a woman's fault with when she's out late.  And you know what is, that is still a rape. You know what it's comparable to to me? It's comparable to me as somebody going out on the sun without sunscreen and laying out in the sunscreen for 10 hours and blaming the sun for their sunburn. Well, if the sun hadn't been so shiny and bright and alluring, I wouldn't have been out there and exposed myself.  The sun was just being the sun. A woman should be able to be a woman without being objectified or told, yeah, I couldn't help myself. I had to lay out in the sun for 10 hours because it was so gorgeous. It was calling me to do that BS. I trust this, we have no tolerance for patients for men who objectify. No. Yeah, and I love that Kalki did it in a poem form because it's almost a lost art form. Nowadays. It made me want to express myself. She was inspiring me. It's like, dang, it's been a long time since I've been poetic and written stuff in that way. Yeah, it's a lost art form. Dying art from the fact that she wrote this. Yeah. You're so talented in many, many ways. Yeah, she's just great. I love that beat behind it. I think it was intentional that it was supposed to be very catchy. She's telling you these really deep and powerful things, but then it kind of goes back to the printing. Tuck, tuck, tuck, tuck, tuck, tuck, tuck. And you're like, ooh, I like that. It's supposed to be comforting to you even though she's telling you. So it's actually, it was quite genius of what she did there. There's actually a play that is about that very same kind of thing. It isn't women's rights and sexualization. It's just, it's about the mechanizations of society and how few people actually kick against the machine. They actually just go into it and get ground up and the machine, but the whole play is functions in the rhythms of the machine. So it's not everybody's cup of tea because they're like, that's going on, but if you know the message, the entire pacing and the structure and the set design and everything is this machine. Very similar to this, where I love the rhythmical connection to the poem because it did convey this machine that's typing and tapping and just brilliant. I thought this was great. Talky would be so fun to talk to. There's so many things that you could talk to her about. Yeah. I just think, Colky, please come on. And I wanna, I know you feel the same way. Boy, would I love to work with her. I would love to do, see and work with this woman. She would be so easy to act with. Yeah. Because she'd be giving you.  You, I really would feel completely, like immediately comes to mind as Nwazidim. To work with Nwazidim, you would know he's gonna give you nothing but treasure and anything you give him, he's gonna go with it and give it right back to you. Oh, just great, great stuff. Great artist. Great job. Well done, Colky. Yeah.


Hands-on, pairing over numeric comparison. Pairing over numeric comparison is very user-friendly because it requires the user only to check that the number displayed on both devices is the same. The STM32WB will indicate during pairing feature exchange that it supports display and some means to either confirm or reject that the number is the same. This could be as simple as a button, for example. In CUPA Mix we need to change the IO capability to display and yes-no, and we can keep the man and the middle protection as required. CUPA Mix already generates the event handler for the numeric comparison value, which is generated by the BLE stack on each pairing. As you can see, the six-digit number is outputted over the UR's traces. The only thing we will change is the format of this number, so it's displayed in decimal and the format is the same as on the phone. The default is a hex. After this, you see the call to ACIGAPNUMERICCOMPERSION VALUE CONFIRMED YES-NO. And as you can see, the value is confirmed by default, so normally you would display the number on the WB side and wait for the user interaction. But for simplicity, we'll keep the confirmation by default. So let's go to the BLE middleware and let's set the IO capabilities to display and yes-no. And we can regenerate the project. And here in the app BLE.C on line 508, we can see the event handler for the numeric comparison value. So here the value is outputted over the traces, so let's just change this format of the number to decimal. And the value will be confirmed by default without any user interaction. So we can compile the code and load it into the device. So now we open the STBLE toolbox, connect to our device and try to read the characteristic. A pairing message pops out. You see the numbers is really the same 751592, so I confirm it on the Android side. It's confirmed by default by the application on WB side and the pairing succeeds and the value is read. And this is the end of the hands-on.


Hello everybody, my name is Daniel and I am MVP of Business Development at Integra Associates. We have been developing electronics and software for over eight years and it's been over two years since we became a technology partner of Estee Microelectronics. Today I'll tell you about our project which is based on Estee components. Last year our long-term client came up with an idea to develop a bespoke keyboard. High customizability was the main feature of the project and users could completely change the case of the keyboard and use their own keys based on top-re switches. What we have actually done in the project? The project scope comprised schematics and PCB design, 3D step model of the PCB, firmware and hardware development. According to the customer requirements the keyboard should be powered by USB Type-C, it should use top-re switches and be compatible with most PC operating systems as a common HID device that doesn't need any additional drivers to operate. Also it should have full N key roll over support and the full time of the entire key method should be about one millisecond. During the R&D process we decided to use STM32F103 as the most suitable solution for this electronic design project and as a result we built a prototype of fully customizable keyboard based on Estee chip. So here is how the board looks like from both sides. Here at the bottom you can see the STM32F103 chip which we used in the project and if we talk about how the fully assembled keyboard looks like I'll show you how the prototype looks like. So basically the main idea is that you can choose any casing or any keypad that you like as soon as they are top compatible and you can use them in your keyboard. So basically you can take the PCB as a base and put on top of it any casing and keypad that you like. This is the main concept of the product. So thank you so much for watching this video. Have a good day, stay safe. If you have any questions feel free to drop us a line message on social networks or a direct message on LinkedIn. Stay safe, bye-bye.


I said it once already, in case I'm going to be handing out salami, actually, let's start doing that now. Take one, pass it down. These are the ingredients. Like I said, if you're allergic to anything, like of these, then you probably don't want to eat it. So, okay. All right. I have 235 slides in 45 minutes, so let's go. All right. I'm not going to introduce myself. No time. I'm not going to tell you where I work, no time. I'm insanely nervous, but I can't tell you about that. I don't have any time. But there's always time for cats. I have a cat. His name is Gorbachev Puff Puff Thunder Horse, and I like him very much. But I didn't realize, like, when I got a cat, like, I thought he would be my best friend and we'd go like bicycling stuff together and like go to the park and swimming and all that. Instead, he just sleeps all the time. So whenever I take photos of him, he's always just yawning. Like that's basically it all the time. It's kind of disappointing, but I love him anyway. And you can follow him on Twitter. His Twitter address is Gorbipuff. So I was going to, I titled this talk like real-time salami, but honestly, like I don't get to see all of you, but maybe once a year. So instead, this is like my summer vacation. I want to tell you guys all about the stuff that I did for the previous year. We are going to talk about salami though, so don't worry. Just there will be other things besides salami. We're actually going to talk about food stuff, work stuff, and hacker stuff. I'm stoked about the hacker stuff. I love RubyConf because I think this is a hacker conference. So I'm really excited to talk about that. First off is the food stuff. Like yesterday Koichi-san gave a presentation and he was a professor. Well, me, I'm a butcher. So we're going to talk about meat-curing. And the first thing I learned about meat-curing was that botulism does not mean anti-robots, which I thought was the cause of the great robot uprising of 1863. And it is not Wikipedia must have its facts wrong. So someone should get on that. But actually the first thing I learned is that when you're making salami, you want to use metric. Please use metric. And the reason you want to do this is because you're never working with recipes with a particular amount. You're always working in percentages.  So seriously use metric when you're doing this. We're going to cover hardware first. I use a wine fridge is what it looks like. It's my wine fridge. I cure all my meats in the wine fridge. And the reason I do that is we need to keep control of the temperature. The temperature needs to stay between 60 and 70 degrees F. I know I said use metric, but I'm not smart enough to switch to Celsius. But I use this for controlling the temperature and this is actually for controlling temperature on kegs like brewing stuff. So people use this a lot for making loggers if I remember correctly, but it also works really well for curing salamis. I use an ionizing humidifier. You need to control the amount of humidity that's in the box. And you want to use an ionizing humidifier because it doesn't emit any heat. So it creates humidity but it's not hot. We don't want our box to get hot. And then I'm lazy so I use a humidity controller. I need to set a particular humidity and this thing keeps the humidity in the box at that particular level. And the last important thing is fans. You need to keep a good airflow inside the box. If you don't have good airflow then your salami will mold and that's kind of gross. So the other hardware you need is grinder. A grinder I use a KitchenAid attachment. This is totally great. You can use it. And it's pretty cheap. The most expensive thing I have is this stuffer and it's totally worth your time. You don't have to get one of these. Good quality one costs about $250. You don't have to get one but it saves you so much time and pain that it's completely worth it. As far as the ingredients are concerned, it's about 80% meat.  And then we calculate the other ingredients based on the meat and fat totals. So we weigh those together and then figure out how much of the other ingredients we need to add to the meat based on that weight. So you use about 0.5% sugar so you take the weight, multiply by 0.5% and you figure out how much dextrose you need to add to the meat. And this is for the bacteria to eat. You introduce bacteria into the meat. The bacteria eats the sugar and produces acid. We also add salt and the reason we add salt is to prevent bad bacteria from growing. You need to add enough salt that bad bacteria, it inhibits the growth of bad bacteria but does not inhibit the growth of the bacteria that you inoculate the meat with. You use pink salt, cure number two, which is a mixture of nitrates and nitrites.  So you don't want to get it mixed up with regular table salt. The thing is it's about 95% salt and about 5% nitrates and nitrites.  You'd probably be like, this is way too salty, I can't eat this much.  The other important thing is that this contains nitrates and nitrites. The nitrates release nitrites over time and nitrites prevent the growth of botulism. So the reason we want to add this to the meat is because we don't want to have botulism in our meat. Also the nitrites change the meat colors and it's pretty obvious to see the top there is zero hours of curing and the bottom is 24 hours and you can see it's definitely changed color between the two.  I think maybe like this, I cured five kilos and I think that was something like a gram or two grams or something like that. I had to buy this scale that only goes up to 100 grams. I totally felt like I was a drug dealer or something buying a scale online. Now this particular bacteria takes about 30 days to cure your meat. You can buy another bacteria that takes less time. Supposedly they produce different flavors. I'm not sure. I've never tried the short curing one. I only do long cures and that's mostly because I got shipped like, I think I got a packet of bacteria that's like maybe, I don't know, 50 grams, which should be enough to last me for the rest of my life, I think. So the next thing that you need to add are spices. Most cured meats are pretty much the same except for the spices. So the meat and fat content is pretty much the same. All this other stuff that we looked at is the same. The only thing that really changes is possibly you increase fat, increase or decrease fat, but mostly it's spices. So the next thing I want to look at is the curing environment. You need to keep wind speed high for the first three days. The first three days we keep the temperature high, so we keep the temperature around 70 degrees and our wine fridge stays between 55 and 65 degrees and that kind of sucks because if you notice from my last graph we need to be at 70 degrees, which is why I have to use that beer thing. So you can either use the beer temperature controller or you can do what I did and hack your fridge. This is a little microcontroller that I have hooked up to the fridge to control it to be 70 degrees. We also keep the humidity at 90% for the first three days and then we drop it down to 65% for the rest of the cure. You need to keep the wind speed high during that 90% humidity because that's really the time when bacteria are going to grow.  I had to resize for this projector and now the arrows are totally wrong. Anyway, right there in the middle we have is the temperature controller and behind it you'll see the humidifier and you can see like, this is a picture from behind the box. The humidifier has a tube that runs into the box and that's actually what pipes the humidity into my box. So the humidifier doesn't take up any room in the box. And I want to tell you a little bit about addiction. This is a face of an addicted cat. These boxes aren't built to have 90% humidity inside, right? So all fridges have a little drip tray in the back where when condensation, when water condenses the water drips out the back and out into your apartment or whatever in a little tray and then that evaporates. But they're not built to handle 90% humidity.  So what I did is I ran a little pipe down to a larger container and that would start to fill up with water and I noticed that my cat was starting to drink the water.   It's condensing on the cooling plate in the back. How is it possible it will taste like salami? And she kept saying, yeah, it tastes like salami, it'll taste like salami. And I'm like, no, no, no. So finally I grab a spoon and I'm like, fine, I'll try it. Try it, it totally tastes like salami. So I had to put a cover on it and actually like tape the cover down so that he wouldn't like lift it off and drink the salami water.  This meat, if any of you have been in the food service industry like me, you'll know about the danger zone. This meat stays in the danger zone for a very long time. So why doesn't it kill us? The reason it doesn't kill us is first off, we add salt and this salt prevents bad bacterial growth. So the next thing that we add is we add nitrite and this kills off botulism but you have to be careful with the nitrite because 22 milligrams per kilogram is a lethal dose.  So you have to be careful. But we use pink salt for safety. It's pink, pink means safety, right? So the next thing that keeps us safe is acid and this is produced by the bacteria that we introduce into the meat. The meat eats the sugar or the bacteria eats the sugar. The bacteria produces acid. The acid prevents other bacteria from growing. And you can actually see this happening by measuring the pH of the meat as you go over time. So what I do to check for safety of my meat is I measure the pH. I bought it this fancy pants pH meter and I read the pH on it. The other thing is water loss. After about 30 days, I measured about a 45% water loss which kind of sucks because it still has the same amount of calories. It's just more compact. It's not nice for somebody who's trying to watch their figure like me, especially when it's sitting next to your desk. Anyway, so 30% minimum water loss is what you need to look for. So if you're curing meat, you can tell when it's done when you hit 30%. I usually go down to 45. But since there's no water, no bacteria or molds can grow after the water has exited the meat. So we have short term safety, which is our salt and nitrite medium term safety, which is the acidity of our meat. And the long term safety, which is the amount of water in the meat. And the final thing is that we can introduce mold. So if we're having a mold problem, we can introduce our own molds to the outside of the salami. If you've been to a fancy meat place, you might have seen salami that's covered with white stuff that is mold. Don't be afraid of it, it actually makes the salami taste better. So now we're gonna move on to work stuff. Sorry, so I wanna talk about streaming and fermented sausages. So we're gonna talk a little bit more about salami. This is a salami party, isn't it? We'll look at how to get the salami date online. But I also wanna show how streaming works in Rails 4. But first I wanna talk about template rendering today in Rails 4. Specifically, we're gonna talk about template rendering, but we're gonna talk about it from a fairly high level. I don't wanna dive into the internals today, and it probably wouldn't fit on my slides. So we're gonna talk about how template rendering works, and then we're gonna contrast that against streaming. Today, template results are buffered. So when you write out all of your ERB or your Hamler or whatever, all of those results are buffered and then sent down to the client. Now the thing that sucks about that is that clients are blocked while they're waiting for Rails to work. So while you're figuring out all that template stuff, calculating it, putting it into memory, the client sitting there going, okay, cool, I'm waiting around, waiting around. And then finally, it gets some data that can actually do some work. It would be nice if we could send down some data so the browser could actually get to work while we're doing some calculations at the same time. The other thing that sucks about this type of template rendering is that the entire page must fit in memory.  The other thing is that we can do IO and CPU calculations in parallel, even in MRI. So we're not gonna get totally into parallelization in MRI today, but you can actually do IO and CPU calculations at the same time. So if we can get that sort of parallelization out of our Ruby process and out of our clients, what is the point of buffering? Why are we buffering all this data? So with that in mind, this is why I created Action Controller Live. Action Controller Live is a module that you can mix into your controllers and get an IO type object on your response. So the way you use it is like this. You mix it in, and then you can do stream.write, and you can actually write out data, and it gets sent down to the client. It gets sent down to the client in real time. I wanted it to act, I wanted response.stream to act like an IO object. And the reason I wanted it to do that is because I buy into the Unix philosophy, which is everything is a file. So I want to treat everything as a file, including my response, which is why I was really set on having an IO object in my response. So I want to look at how we actually implement this inside of Rails. Like how do we actually do this? Let's dive into the internals of how Action Controller Live works. We're gonna look under the hood and see how it works. This is the API that we want to have. Like this is what we want it to look like. We want to set a response, status, set some headers, write to our stream, and close the stream off. So we need to accomplish this, but what we have is this. This is the rack API. We have to return all of that stuff at the same time. Even though we want to be able to do that piecemeal, but rack wants us to return it in one step. Ideally, we could calculate this stuff lazily and write it out to the client as soon as we calculate it. So the way that we start is we need to wrap this with a response object. Wrap with a response object that looks something like this. And I've actually simulated Rails down here at the bottom. Like this is basically what happens inside of Rails. We set the response on the controller. We call your action on the controller. And then we have to return all of this data back up the rack stack. But the problem here is that we're still buffering. We haven't actually solved our problem. You can write to the stream, but the stream is still buffered. So how do we solve this? We need to be able to do calculations in the controller and return back up the stack at the same time. We do that with a thread. So we can say, okay, let's call the controller index in a thread. Cool. So now we're calculating the controller index in one thread but returning up the stack in the other. The problem with this is that, well, maybe you didn't finish writing out the headers. And it's already returned up the stack and started writing data out to the client. We're screwed. What do we do? We have to block. We need to block right here, right there, stream.await. We need to block there until somebody's actually written data out. So you have to calculate all of your headers, set all the headers, and then as soon as you actually want to write the body of the response, then we'll say, okay, time to return back up the stack and start emitting data to our response. The way we do this, the way that we accomplish this is we use a latch inside of the buffer. We say, okay, the main thread calls a wait, and a wait puts the main thread to sleep. And the main thread just sits there until somebody calls release on the latch. Now when you say response.stream.write, that says, okay, we're now going to release the latch. And once we've released the latch, then the main thread comes back awake and says, okay, let's return back up the stack. So this way we can actually stream data out to the client and not have our headers get all messed up. So this is cool, but what can we do with this? Like why should we be excited about this particular thing? I'm excited about this from a Rails internal's perspective. And I'll show you why. The reason I'm excited is because I want to be able to do streaming ERB. We can do this today, but it's kind of hacks. And I'm going to show you how we can accomplish this with an IO object. And the way we can discover how to do this is if we take a look at ERB, we can create a new ERB template here and we can actually look at the source of the ERB template. This is how you do it. Doc.source will show you the source. And this is what the source looks like. This is our ERB template compiled down. And you can see we have a string there. We can catinate to the string and we set some encoding on it and we're done. But we can actually subclass the ERB template and set the output variable to be whatever we want to. And the method name to be whatever we want to. So we don't have to use concat and we don't have to use a string. Which means that this code will turn our ERB template into this. Standard out.write whatever, right? And now we're actually writing to a stream. We run this program and boom, we see output on standard out. And the reason I like this approach is because we can say, okay, well, we can change the IO object to anything we want. As long as it quacks like an IO object. Which means that we can choose streaming or buffering depending on the IO object. Our code path stays exactly the same. Whereas today, if you look at the source code today, we actually have two distinct code paths. One for doing our normal template rendering and the other one for if you say like render streaming true. It's like two completely different code paths. If we actually had ERB templates that did streaming, we could just make this decision based on the type of IO object that we have. And we don't have to have multiple code paths. The other reason I'm excited about this is for use from web applications. An obvious use for this is infinite streams. But I don't think that that's the most interesting use case for using IO objects on the response stream. I think the most interesting use case is server-scent events. Now, a server-scent event, this is what a server-scent event response looks like. This is the, like if we telnet it in and took a look at the response, this is what it looks like. Now, you can see the content type there is text event stream. And each chunk of the event, each event has an optional name. So this one's name's ping. And then we have a data payload, which can be anything. But most people just do a JSON encoded, like whatever. Just encode your stuff as JSON and put that in the payload. Now, on the client side of this, we, in the JavaScript that's executed on the client side, we say, okay, we create a new event source.  Thank you, resizing, awesome. Anyway, it's there, that slash control, that is our event source. And that makes our quest to the server, and that's where our server-scent events come from. Now we were listening for, man, yeah, keynote, whew. Anyway, so reload is the name of the event that we're looking for. And every time we get that event, this function gets executed. And in this particular case, we're just reloading the web page, right? Now with this, with this JavaScript, we can actually do real-time browser communication.  We'll zoom in. This is a demo of doing some real-time, real-time communication with the browser. So we're loading a page here, this is our user's page, my user's page. And hopefully I'll zoom in on this, please. Well, okay, yes. We're changing the file, and you can see when we change the file, the page gets automatically reloaded. So cool, we can see that reloading, and I'm a CSS master. I'm totally changing the CSS there. Look at these styles, beautiful. It's why I'm paid the big bucks, it's beautiful. Now the other thing I'm gonna demo here is we're like, I'm opening up the Rails console there, and I'm actually creating a user. I know this is small, so I'm going to describe it. I create a user, and you'll see when the user is created, the page reloads. And we actually have a new user listed there on the page. So it's automatically reloading when we manipulate the database. So how does this magic work? The magic in this particular application works this way. We have web server, which is Puma, FS events, watches our file system, and these are running in the same process. When FS events notices that our file system changed, it tells the browser. We send a message down to the browser. The way that I did the database manipulation side is that the server actually starts up a DRB server inside the same process as the web server. Our console connects to the DRB server over a socket, a well-known, just some well-known port.  And then that sends a message down to the browser, and the browser can reload. So this is how we can do inter-process communication and send events to the browser that way. So I told you we would talk about Salami, so let's do that. Real-time Salami. I've actually built a Salami monitoring system for my box. On the left there is a Beagle board. On the right is a TI launch pad. It's similar to what is the other one? I can't remember. Arduino, it's similar to an Arduino. That actually pulls the data. I have a sensor mounted inside the box that pulls data off the sensor, and then posts to a website, and I actually broadcast the data. And the way that I do that is I have an observer sitting in process. I'm using a threaded web server. The Salami posts to the create action here, and then that sends a message to the observer. The observer notifies any browsers that are sitting on any threads, sitting on the index, and they're able to update. So I actually have a message bus that's built on top of observable from standard library, and when a browser hits the index page, we just add an observer. And every time the observer fires, that code block is executed, and we add an event to the queue. And then the queue is consumed inside the main thread, and that is written out to the response. Our publisher is much more simple. Our publisher just adds our JSON data onto the message bus. Just publishes to the message bus, and then everybody else is notified. And this is really cool, except that we don't have any feedback. So I wanted to have feedback, and the way I did that was I integrated G charts and SSEs, so whenever I got a notification, it would update my chart. So now we can see I have a chart of my, this is like my danger room. Have it on a monitor, I'm like, okay, what is the humidity of my box today? That top blue line is the humidity, and the bottom red line, that's actually my temperature. This isn't an actual graph of my Salami box, I was actually just blowing on it because, it's not like the Salami box isn't actually that interesting. That graph isn't actually that fun. So, okay, my God, I've only done 110 slides. Hacker stuff, we're good, I actually got 20 minutes. We're doing good, okay, great. All right, hacker stuff, yes, hacker stuff. We're gonna talk about the Ruby VM. So we're gonna talk about the Ruby virtual machine a bit, and then we're gonna talk about detrace stuff, and then I think we'll finish up. The Ruby virtual machine is stack based, and any of you that have used an HP calculator, like I used in high school, will be familiar with stack based, stack based virtual machines. I actually loved using an HP calculator in school because people will be like, hey, can I borrow your calculator? And I'd be like, yeah, totally. And then they'd be like, well, how do you, I don't understand how you add numbers, it doesn't work. And then I'm like, well, you just do two, enter five plus.  And I'm like, thanks. So anyway, I thought that the best way to demo a stack based virtual machine would be with PostScript. So this is the GhostScript interactive console, and PostScript is all stack based. So we start out, the right hand side is our stack, and the left hand side is actually the GhostScript REPL. So we do two, and then we hit enter, and when we hit enter, two is pushed onto the stack. We hit three, and then we hit enter, and three is pushed onto the stack.  Stack just displays the stack, and then pop, pops a value off the stack. So if we actually want to get access to the byte code that's written in Ruby, well, we just use the Ruby VM instruction sequence, this code here. We say, okay, this actually compiles it down. So is on the left hand side is our compiled instruction sequence, and we can disassemble it by saying puts is.disasm, and that will show us the instruction sequences. And I have more messed up arrows. On the left side is the instruction names, and on the right side is the parameters to those instruction names. But we read those names, and you're just immediately, you're just thinking to yourself, what does it mean? And it's easy to figure out what it means. You just go into the Ruby source code and find this file, insns.def. It has all of the byte code written out and documentation above each of the byte code names. It's actually very simple to read. You just read the dot, all of them are documented. You just look for the byte code that you want to know about, and then read the documentation there, and it's actually very easy to understand. So the byte code that we're dealing with in this example is trace, put object, opt plus, and leave. Trace is for set trace func. I don't know if you guys have looked at this, but it's like basically you can get events of what's happening in your machine, you register a function. Put object just pushes onto the stack, opt plus actually does the addition, and then leaves that particular scope. So we're gonna take a slight detour, a little bit of a slight detour that may or may not be related to what we're looking at. We can actually translate these to PostScript. So on the left side is our function, this is PostScript. On the left side is our function definition. On the right side is the actual function code itself. So we're defining trace, put object, opt plus, and leave. Which means that we define that in GoScript, and we can actually run the Ruby byte code in PostScript here. So that is a translation of the Ruby byte code, and we can get access to the Ruby byte code in Ruby, manipulate it, and then translate it into something that we can run in PostScript. So what does this mean? 2013, print Ruby. Okay, I'm telling you now, 2013, print Ruby. And the thing that's awesome about this is massively distributed. You can distribute this out to all of your printers everywhere. Everywhere. People will be like, why can't I print anything? And you'll be like, listen, man, it's the cloud. The cloud of printers. Look, you don't need to print anything. This is the future of distributed computing. So yes, exactly. Take that, Node.js. I've actually been studying Node.js lately, and I discovered that the only important languages are CEC++, JavaScript, and PostScript, in fact. Sorry, that wasn't a slight detour. It was a massive detour, I apologize. So let's actually, let's go to our actual slight detour, which is, this is the actual slight detour. We can get our instruction sequences by calling 2A. So this gives us, this gives us access to the instruction sequences. Don't read this, you don't need to. You can just see, here are our instruction sequences. It's cool, we can do that with that object. We can eval these instructions by just calling eval, so that runs them. And the other thing we can do is, eval, there we go. That runs them, and the other thing, we can't do this.  So we can't come up with our own, we can't come up with our own instruction sequences and load them. Can't do it, or can we? If you go take a look at icquents.dev, more messed up arrows. Anyway, if you go look at icquents.dev, you'll see that there's a load that's commented out, and a function pointer there, ics.load. And we can actually get access to that via Ruby standard library with dl. So this, don't read this, don't bother, I'm going to describe it. What we do is we say, okay, well, let's get a handle to the, those arrows were totally helpful, weren't they? Anyway, we get a handle to the shared library and we look up that function. We can get the address of the function and we can create a pointer to that function. And then we can actually call that function using ffi from ruby. Which means that we can monkey patch a load onto the instruction sequence and actually eval new instructions. I'm sure Koichi is getting upset with me right now, I'm sorry. So now we can say, okay, let's compile some sequences and then load them and then eval them. So we can actually take a sequence, copy it over to a new one and eval, which means that we can go in and do manipulations on the instruction sequences and then load them. So this changes all of our, this particular code changes all of our numbers to tens. So we'll do all of our calculations, just, all right, we change it all to tens, boom, eval, that's all we need, we're done. So I highly recommend this technique for when your code is a little too readable, or when meta just isn't meta enough. And the final thing that I recommend this for is if you really need to take your app from low scale to raffle scale, like this is, this is it. The other thing, this works on every Ruby, I personally guarantee it. What? I am not lying. No, I'm not lying. Okay, let's have a talk about this later, okay buddy? Anyway, what else can we do with this? Those are some fun hacks, but what else can we do with it? We can do some micro-optimizations, okay? So the first thing that we can do is these micro-optimizations and hopefully you guys don't know about this, I hope. The first thing we can do is we can do some benchmarks. We'll have some benchmarks, like we find a slow bit in our code. A friend of mine from GitHub says, hey, Aaron, Rails is super slow, why is it slow? This thing is slow, and I'm like, I don't know, I'll take a look at it, and he sends me a test case. And this is the test case that he sent me. So I'm like, okay, let's take a look, ah, the graph, useless. All right, one side of this graph is Errol and the other side of it is MySQL2. And actually, if we were able to look at the top of the graph, the top of the graph would be ActiveRecordRelation. And if we look at these, we can see we're spending a lot of time in Errol. And quick PSA, ActiveRecordRelation, is not Errol. And the way that this works inside of ActiveRecord is, let's say, if you do user.star.food.bar.count, all the red objects there, all those red boxes, those are ActiveRelation instances. So we create new ActiveRelation, Active, the instance, and then SQLAST, and then we actually query the database. And these ActiveRecordRelation objects are actually trees. And the AST is a tree, so we're actually building a tree to build a tree. And when I realized that, I was like, yo, dog, awesome, two trees. Why do we have two trees, if you wanna know, ask me later. So here's this awesome graph again. Anyway, you saw this. Let's take a look at the code. So I wanted to speed up the Errol code, and I'm like, okay, well, let's take a look at it. Spending a lot of time in here, and this is a sample of the code. This is what it looks like. And if you look at this, you wonder, I was like, well, okay. Spending a lot of time in GC, and we're actually creating a lot of objects here. How many objects are we creating? How many strings are we creating? All of you pick a number inside of your head of how many strings we're creating, I will tell you the answer here.  It's not a trick quiz. Just think about it. There are six strings created, and those arrows are completely unhelpful. But where they are created here is this string literal creates, that string literal, the select creates a string object. Doing that middle interpolation there, that creates a string object. You'll see there's a little space after the interpolation. That's another string object. And all of those get joined together, which makes another string object. Evaluating that blank string there in the join, that creates a string object. And actually joining all of them together is another string object. So this function is actually creating six string objects. So if we run this, if we put this into the Ruby virtual machine compiler, and look at the instruction sequences, we can see, okay, these are the instruction sequences. This is the instruction sequence for the string literal selected. We'll see that it says put string. And if we go look at the source for put string, we'll eventually find that it calls this rbster resurrect. And you can see there it's clearly calling string alloc, which is allocating a string. It's easy to prove that these string literals are actually creating new string objects, we can just loop over them and call object ID. And you can see there clearly, clearly these are new string objects. All of the IDs are different. Now if we look at the interpolation, we see this. That first one there, that from, that's a put object. And then down there we're starting to call a method. And then you see we call put string on that space, line 25 there. And then we call can cat strings. These arrows are probably not gonna, wow, huh, that one lined up, cool. Anyway, so if we go look at put object, we can see, well, it does nothing. Awesome, we're not creating any objects, we're just putting an object onto the stack. That's great. So the long and short of it is when we have an interpolation like this, and these arrows don't totally suck.  So all of those strings in the middle actually create new string objects that just get thrown away. They can never be manipulated but they're just thrown away. Though I have to say this, I was preparing these slides and I'm like, it's not lining up. I don't see, I saw this problem before. I saw this problem before, why isn't it happening? Well, it turns out it is fixed in 2.0. Thank you, Koichi-san. So now in 2.0, this is put objects, put objects, put objects, and finally it can cat string. So doing string interpolation in Ruby 2.0 will only result in one string being allocated. So step four, I updated the code and the way that I did this is, I changed some of these string literals to be constants. And we can do that because, well, we're never manipulating those constants. Inside that function, we're never actually mutating them. And all of those are just going to result in a put object. Let me just call it put object. So I changed a lot of those to be constants. And then I started using string append. And now our string allocations are only there and there. So we reduced it from six string allocations down to two. And running this particular benchmark with Rails, I found that we had an 18% reduction in GC invocations. And actually an 18% reduction in GC time, which is pretty nice. But I have to say, please, please, please, please, please, optimize for readability first. Like looking at all these string incatenations and these crazy, like constants floating around in there, you can tell it's been raffle scaled, but it's totally hard to read. So find your bottlenecks, optimize for readability first, then find your bottlenecks, then change your code. So the next thing I want to look at is detrace. We only have seven minutes and like 70 slides. Okay, I need to speed up. So detrace is a tool for monitoring our processes. This is what a D probe looks like. So the top there, we specify the function that we want to monitor. That second line, we specify a predicate so we can say like only fire this probe during these particular, I don't know, in this particular condition, then we execute this decode. And the Ruby probes that we have, or that I have added, these are too long, but I would like, this is too long, but I have divided them into seconds. We have function probes, things for, things for monitoring the functions that you call in your Ruby codes. You can say like, oh, this method's called, this method's called, or returned, object creations, object creation probes, GC actions, and Ruby internal stuff. So like this one's looking at the virtual machine itself. So I want to take this and I want to take these tools and use them to inspect Rails boot time. And I have to say like, there's no really incredible, like no revelations in this particular section. We're just going to study it. I want to look at how we use D to study these. And we can take this, like, we're going to look at how to use D basically, detrace. The first thing, first example we're going to do is count the instruction sequences that are executed. So this is the script that we're using. This is my test script that I'm using throughout all of these examples.  So all I'm really doing here is profiling app boot time. And when we run this, when we run this decode, we find out, well, the number one opcode that's being executed is the trace opcode. And the trace opcode is the one that does set trace fun. And I'm like, well, wow, that's our number one opcode. Why don't we disable it? There's a way to disable it. You can set the compile options globally on the Ruby virtual machine, and this actually removes the trace instructions. And also this particular function works on every Ruby guaranteed, I promise. It's my seal of approval. Ah, resize that, it says seal of approval. Oh well. No, I'm not. Yes, you are. No, I'm not. So we run it again and we see the output here. Get local, now get local is our top one. We don't have trace anymore. Trace is gone. Now the question is, is this faster? Is it faster? We got rid of the trace instruction and is our app boot time any faster? So I took 100 samples of loading config environment and then I did a little statistics on it and found that our mean time, the top one, that's our mean time with the trace instruction. And the bottom one is our mean time without the trace instruction. So it looks like it might be possibly slightly faster, but then when we look at the standard deviation, we see the standard deviation is like 0.05 seconds, right? So this basically means no. It's not faster at all. We didn't do anything. So eliminating the top instruction didn't save us any time. The next thing we wanna look at is, well what is our favorite instruction? What instruction are we spending the most time in? Like where are we spending most of our time in the Ruby virtual machine? And the way we can do this is we can set up a timer in D. So this top probe, all this does is execute this code every 5,000 hertz. So every 5,000 hertz on your machine, it does a sample. This bottom one just says okay, anytime we run a Ruby instruction, save it off, right? We just save off the Ruby instruction. And then this timer, this timer says what instruction was just executed, count them up. So we're taking a sample, we're taking a sample of the instructions that are being run. So when we look at that and we get this count, this count doesn't actually really mean anything except that they're relative to each other. So we know that when we're sampling the process, we're most likely to be inside of a send instruction. This actually shouldn't be surprising to you if you were in Koichi's talk yesterday. So if you wanna look at how to find where to speed up the Ruby VM, that send instruction is where we need to go. If we can speed up the send instruction, then we're really going to speed up the Ruby VM. And if we looked at this, if we looked at the entire sample for this, we would see that trace, yep, the arrow is totally messed up. But trace is like way up there at the top. We're spending like basically zero time in trace. The next thing I took a look at was GC time. Shoot three minutes and 30 slides. Okay, GC time. We can measure GC time, measure the marks. When we mark, when we sweep, and then total up that time and look at the total time for our process. Ah man, come on. So when we look at that, we can see like, well, okay, we're spending 24% of our time in the garbage collector when we boot Rails. The next thing I went and looked at was compile time. Oh, all these times are going to be in nanoseconds unless I say otherwise. So then we look at compile time. So we can monitor our compile time and this is actually parsing the code and compiling it. So this is actually reading the file, turning it into instruction sequences. So that's the amount of time, that's what this is measuring. And when we look at that, we're spending about 21% of our time doing compilations.  So I disabled the GC. We're spending about 21% of our time in compile time. And the next thing I want to look at is searching. And what I mean by searching is when you say like require foo, we actually have to go search, okay, we go search loaded features. Ruby says, hey, have you required this file already? If you've required it, then we need to exit. If you haven't required it yet, then we need to figure out where this file is. So this particular probe wraps that function. It says, okay, we're going to calculate how much time Ruby spends searching for your file. So this particular one prints out the timestamp that we search and the amount of time that it took to search for that particular file and the file that we were searching for. So the statistics on this are when I ran this benchmark, again with GC disabled, I found that 30% of the boot time in this Rails app was just searching for files. This wasn't requiring them doing GCs or anything. This was literally trying to find the files on your file system. This app had, what, 1600 files, 1650 files.  So that's what the graph looked like and I thought, well, okay, maybe it's linear growth. I don't know the equation or I don't know the algorithm for finding these files and I think, well, maybe it's linear. So I did a linear fit on this and found that, well, okay, this is actually what our graph looks like and these numbers are in nanoseconds, right? So our coefficient there is only 174 nanoseconds. So as we're going along in time, we only increase 174 nanoseconds. This is basically flat, that's like nothing. I don't even know what 174 nanoseconds is. So crap, 45 minutes, but you gotta see this. Okay, bug 7158, somebody filed a bug saying requires too slow. I think it's too slow. 30% of app boot should not be a file require. They attached some patches and there have been some back and forth so I decided to apply the patch and measure the amount of time. I did that same test, 16% of the boot time was now searching for files. These are graphs comparing them. The graph on the left hand side is our total program time, how much it took to boot the application. The one on the right is how much time we were spending in search.  The green is how much time we were spending after the patch and if we actually sort the times we can see the red line there at the bottom is the times after the patch, the black line is before the patch. So we can actually see a drastic difference in the time it takes for searching required files. Now if we actually run the process itself we can see okay, that top one took about 1.5 seconds and the bottom one took about 1.1 so we saved about 0.4 seconds. Now if we combine all these graphs together we can see before that particular patch we're spending 30% of our time finding the files. The rest of our time, that 25%, that could be in the Ruby virtual machine. So even though Koichi did those awesome, those awesome speed improvements for the virtual machine we're not seeing any of that benefit on boot time because that percentage is so small. Now after this particular patch is applied we're only spending 16% of our time in fine files so now during boot time those VM optimizations actually help us. So this particular ticket I love it and I hope that this patch gets applied. So I wanna end this talk with some of my very favorite yearbook phrases, stay cool, never change. But really I wanted to end this with work, eat, hack, try Ruby 2.0 and I'll see you all next year. Thank you.


How's it going everyone Caleb here with the late in sports cards next tonight? We've got 2021 tops chrome f1 sapphire edition this year is gonna be a five box break number 13 The results are right here for you. They're also linked in the chat. Good luck everyone. Let's do it That's pretty Let's see Oh, yeah, all right, here we go Samia there Starting out with a Sebastian Vectel nice that'll be number 299 nice start Ashton Martin There you go Louis Hamilton right away as well Mercedes Times two couple of them Landon Norris McLaren also gonna be another Louis Hamilton there There's Sadie's Beauty and Jan Mochox over Romero F2 driving their Carlin Jehan Deruva la It's gonna be Oscar Pastrari. That is the 50 nice F2 Prima. There you go. It's a 50 future stars Sebastian Vettel Brands toasts Max Verstappen nice one Red Bull Christian Lugard F2 George Russell George Russell, excuse me Williams racing nice And then a Robert Schwartzman F2 Prima another Yuki Oh Number 2100 Christian Orner Red Bull there you go Nicholas Latifi Williams racing Roy Marcus Armstrong Max Verstappen Red Bull Landon Norris McLaren and a Louis Hamilton The one from Mercedes there pure ghastly Alpha Tori, there you go nice Another Christian Orner there this one this time is gonna be the yellow to 199 another one for your Red Bull racing and Tonyo Givinazzi as well as a Voltaire Botas Nicholas Latifi Esteban Ocon You got a lirons and deli and a George Russell you have another George Russell Mercedes Next box up one chrome sapphire edition you on Empty box there and good luck all to Alonzo Rolf Bush long to compost Louis Hamilton And a Dan at tic-tom peer ghastly Nicholas the teary that time that'll be number to 199 Nicholas the teary or the Tee-Fee excuse me Sergio Perez and Charles Leclerc You go nice one Leclerc Ferrari Nikita Mays pin Gunther Steiner And a Mick Schumacher Max Verstappen Yes, you can't hit autos there just No, you can't it I was just kidding. You can just sit low numbered color in this Sorry, I was thinking of different products Lou Ham there nice Lou Ham Botas and Max Verstappen Each sapphire is just a little bit different. That's correct Davidi Brevo Future stars Robert Schwartzman one of 99 Solid there for Prima racing ego This F2 hits and then a Lou Ham there awesome Nicholas the Tee-Fee Nick Schumacher that time that's gonna be to 100 Haas F1 team there Louis Hamilton and Wolf Bosch on future stars Sergio Perez Daniel Ricardo Sebastian Vettel And a Oscar Piestrasi Prima F2 there Carlos Sainz Christian Lungard future stars number 299 Art Grand Prix there you go. It's gonna be Sergio Perez and Voltaire Botas Next one up. Keep it going. Good luck Empty there. Let's continue Simone Rastia Daniel Ricardo So it's a wolf and the key to maize pin. Yeah, you're looking more for like the SSPs and the specific card numbers on the back out of the sets Their base versions So you can see each person has multiple different cards in the sets Each number of their card has a different value Andre Sadelle nice one there Max Verstappen Beautiful 15 of 15 Boom Great card there Red Bull Wow Card number three big man Card number three is the base version of Verstappen big card Congrats Red Bull that is drew em Like I was just saying you want to find this more so than like a car insert or one of the ones where he's holding like a Trophy you want to find the base versions card number three is that Also a lot of the time they have a similar pose to what you see right here That's another great way to identify it. Congrats drew and that'll get magged man Make shoe mocker and so Louis Hamilton. So for example here This would not be like a base Lou Hammond. You can see it's card 140 So that's kind of what we're talking about if you are not familiar with any F1 Sapphire products or any F1 is it's the same for chrome F1 as well George Russell here Verstappen George Russell again Card 35 and another George Russell. Holy George Russell bag Portraits. Thank you, Ender. Nope. I appreciate that Voltaire boat us It's gonna be a Lou Hamm number someone 99 Louis Hamilton there Spain winner card Daniel Ricardo and Charles Leclerc. Yeah, I was blinking on the word. Thank you Daniel Ricardo Charles Leclerc Card 32 on the Leclerc nice Lance stroll and a Sebastian Vitell Make shoe mocker Fernando Alonso pure ghastly and a Frederick Vestier Go on use out It's Max Verstappen green to 75 Driver of the day hungry nice 75 Voltaire boat us any Matia Vinoto Max Verstappen We've got Dan tic-tum.  Good luck To May's pin Max Verstappen green again wow to 75 Have a break Red Bull there you go Drew Dan tic-tum future stars Sergio Perez What's up being We're stopping Luham nice It's the portrait of him card one and then that's also gonna be the Charles Leclerc portrait card 11 nice pack Gunther Steiner Nice pack there David Brevo Maybe you I think this Latifi again mix shoe mocker and a Voltaire boat us Sergio Perez Eliseo de Leda is a future stars to 99 Nice one You go that is race lab you go Max Verstappen Spend good being how's your night going man? Spend good Daniel Ricardo Wow another Max Verstappen card number three number to 199 boom Have a break Red Bull congrats again Drew that's so sick man Luham 56 and 150 break man Congrats Red Bull color signs Sergio Perez Sergio Perez is number to 50 nice gold Red Bull again great Sergio Perez now Future stars Rolf Bolshong and Sebastian Betel Grand Prix there He's soon out by a gypsy queen with it. We got it Growing the Sonny there Let's get those meta's who sold out in late in gaming with Brad guys to 199 Medezoo Oscar Piastri future stars and Sergio Perez Caleb said if Medezoo doesn't sell out, he's gonna fire me Fernando Alonso Voltaire boat us only Sam said that actually N.A. J Has that power and he said my job is on the line Really that's crazy Caleb promoted himself Empty let's get to it guys last one here Nice Verstappen That is a Kimi Rikokin 75 there Alfa Romero nice card Luham and Luham Couple more Luhans him again That is a Zao gonna use out future stars 61 nice Sit there Rolf Bolshong future and Sebastian Betel The solid break and congrats to Red Bull. See if anyone else can grab a big one here by the end Verstappen That is Esteban O'Conn to 75 there L pine Hill L pine Oscar Piastri future stars and Sergio Perez Guyermi Samia future stars Yeah, yellow there Yellow to 199 is Theo Porsche. I have two arts military boat us Another yeah, huh To say the least under yeah, please. We need like a big Leclerc here or something like that big Luham come on military boat us There's a Luham Card 50 another Luham has been a lot of Luhams, but she's not like one really really big one, you know Couple to go y'all 11 gold to 50 Charles Lecler boom Ferrari congrats on that one Brayden K That's what I am talking about Well done Ferrari That will get mad There's a Yuki and a Jan Let's go right on right on cue to a low number Yep Max Verstappen Sebastian Mattel and fans What a break man Biggin what a break Luham Sergio Perez it would have been a good break before that car. Yeah, George Russell In a Robert Schwartzman guys, thanks again so much for joining congrats again Brayden congrats again Drew Insurance of course is available on the website for the big hits We go let's do one more time guys on the recap had a Theo Esteban O'Conn Kimmy Roy Nassani Sergio Perez gold LACO Delada Max Verstappen Dan at tiktok Max Verstappen Lewis Hamilton We've got a Christian Lungardo Mick Schumacher Robert Schwartzman Nicholas Latifi Christian Orner Christian Orner Oscar P. Astrasa Sebastian Vitell the big Max Verstappen You check on one of the Sergio Perez's for an SP Which one would be you'd be a recent pack wherever the recent stuff is I'll look at it in a second she's eat Charles Leclerc Yeah, is that the one and a Verstappen I think you're right here Card for that's got to be a very issue. Yep. We'll get that magged as well then that's a great ending Red Bull once again Unbelievable Drew a good good catch on that she's eating and thank you again everyone for joining We'll have those all protected up and right out to you


That's strong. One of my favorite NES games ever is Mike Tyson's Punch-Out. It perfectly follows the old school Nintendo formula of super basic, easy to learn gameplay and jazzing it up with a ton of charm, wacky characters, and great music. Of course, many NES classics were made that much better on the Super Nintendo, so how does Super Punch-Out measure up? First of all, Super Punch-Out is much closer to its original arcade incarnation than it is to Mike Tyson's Punch-Out on NES. So it really doesn't look or sound much like a sequel at all. There's only one round instead of three, and the clock runs in real time. No timeouts or pauses at all, so that robs the opportunity for funny dialogue from Doc who doesn't appear in the game at all, bummer. There's no decisions either, you have to score a knockout. I think that's an improvement. It makes the results more cut and dried, instead of the computer screwing you out of a victory by decision after you knocked down your opponent three times and you were only knocked down once. Man, I freaking hated that about Punch-Out. Anyway, this game has a couple extra features, like for example, the momentum meter, which fluctuates as you land punches and as you get hit. When it fills up, you can launch haymakers and uppercuts that do serious damage. There's six returning characters, three from the original game, Walt Bull, Mr. Sandman, and the champion, Super Macho Man. And there's three coming back from the Super Punch-Out arcade game, Bear Hugger, Piston Hurricane, and Dragon Chan. That's in addition to ten new characters in which there's a wide spectrum of personalities. Bob Charlie, is this the inspiration for Kofi Kingston? Anyway, there's lots of recycling of patterns and quite a bit of palette swaps, too, which is disappointing. The last two fighters are the exact same guy. Come on! Super Punch-Out is much harder than the original, but that shouldn't be surprising. The game is predicated on pattern recognition, and of course there's an inherent limit on patterns you can have on an NES game. The fighting styles and patterns on Super Punch-Out are much more complex. So if you want to get good at this game, you gotta put in the time. If you do, you're rewarded with unlocking the special circuit, so that's pretty cool. I have to mention the graphics here are freaking great. This is some top-notch pixel art. The game is memorable-looking, the kind where you take one-half second glance at the screen and you immediately know the game is Super Punch-Out. The special effects are well done, too, like the blindness effect versus masked muscle. Although I have to mention, your character looks like an anime Jim McMahon. What's with that? Anyway, I think Super Punch-Out is a very good game, easily the best boxing game on the Super Nintendo, but the characters just aren't as memorable this time around. The oversized personalities are what really make a game like this fun, in my opinion. As it is, Super Punch-Out is still technically solid, and objectively, it's gotta be a top 40 or maybe even a top 30 Super Nintendo game, but it lacks the personality that made its predecessor so much fun.