Hey, welcome back to another episode of the Ruby Rogues podcast. This week,
on our panel we have Valentino Stole, you know, Charles Maxwells from
top ed Dev's. We've got a special guest and that is Samuel Williams.
Samuel, do you want to introduce yourself? Let people know who you are
and why we all love you? Thank you? Yeah, my name is
Samuel. I live in New Zealand and my kid's right here with me in
the morning morning routine, and and I'm having a coffee, which is awesome.
What time is it in New Zealand. Yes, am a little past
eight am. Actually, anyway, I was imagining it was like four am
or something. So I don't feel healthy anymore. I have had meetings at
four am. I'm sure miss schedule a meeting and I'm like, okay,
yeah, I'm on mountain time and it's it's just past noon here, so
I was like, oh, okay, okay. Yeah. So my back
in background is in software engineering. I did a bit of computer vision growing
up in the university. I did an m C and outdoor augmented reality.
And I've always been patient about solving problems. I've never really been satisfied with
just the status quo or this is good enough, and maybe that's informed the
way that I've looked looked at the software that we have today and thought about
maybe but what we could do better? Right? Hey, folks, this
is Charles Maxwell. I've been talking to a bunch of people that want to
update their resume and find a better job, and I figure, well,
why not just share my resume? So you if you go to top endevs
dot com slash resume, enter your name and email address, then you'll get
a copy of the resume that I use that I've used through freelancing, through
my most of my career, as I've kind of refined it and tweaked it
to get me the jobs that I want. Like I said, top endevs
dot com slash resume, we'll get you that and you can just kind of
use the formatting. It comes in word and pages formats and you can just
fill it in from there. Cool. Yeah, And I interviewed you for
the Ruby Dev Summit. People can go check that out Rubydevsummit dot com.
But yeah, we talked about a SINC and Falcon and I thought, you
know this, there's some great stuff here that we should just talk about on
Ruby rogues and then you know, we kind of got into future Ruby and
some of the things involved there as part of the summit. So so yeah,
do you want to just kind of give us the ten thousand foot view
on ACNC and then maybe we can get into what falcon does in a minute.
So acink is an interface which gives a vent drivenking currency to Ruby,
provides vendronking currency and as to ays being designed as to give give engineers like
the best possible experience with concurrency, and so in that regard that that sort
of mental model and form like a lot of the choices and the design choices.
So acinc provides task based concurrency. It doesn't require any special keywords for
asynchronous behavior, like saying jobs would be require a single weight, and it
tries to be as efficient as possible, but it also sometimes chooses develop a
happiness over efficiency to make it easier because asynchronous programming can be pretty tricky and
giving people like good logging, good feedback when things go wrong is really important
actually, and I don't think we've solved all of those problems, but we're
definitely like that. That's the mental model of a sing So ACNC provides this
as ventrin concurrency, and on top of that you can build other things.
And when the first proof of concept that are you know, major for a
concept that I was really fascinated and was building web server because because why not?
And is this that's what this is where Falcon came from. Okay,
Falcon basically evolved from let's try that, try it and see what we can
do with a and what the performance is like, and then we can actually
measure things and do some interesting real world comparisons. So I have a question
here that I'm kind of thinking about. And I mean some of this you
said event driven, and that just made my mind think about well one arguments
that I've had with people over no js but also right because there are ruby
anyway. But the other the other question I have is way back in the
day, we had event machine, and a couple of weeks ago we interviewed
or I interviewed Marc Andre Cornerier who built Thin and know a lot of that
was kind of built on some of the stuff with event machine. So what
what's different between say acinc and event machine and then maybe thin and Falcon.
Yeah, that's actually a great question, as in the side actually maintained thin
slightly. Thin was sort of languishing a bit, and I got involved in
maintaining it, and I learned quite a lot about it as well. So
I really like I like exploring the ecosystem and seeing the different, different,
different, different kinds of implementation. So to your point, event machine versus
a SYNC or the modern version of acing, actually is a gym behind it
called io event and that's the actual event loop, the thing that provides the
event loop. But surprisingly, or maybe surprisingly Ruby she is quite a rich
history of event driven architectures. It's not just event machine, and like a
SYNC, there's also celluloid em synchrony. Never block is one that many people
haven't heard of. It was an interesting experiment kind of similarly so long.
Yeah, and there's a handful of the ones. If I go digging in
my notes, i'll be able to pull them out. But you know,
I suppose my point is there have been like a lot of keen minds in
the Ruby community experimenting with this, and it's interesting to compare the different approaches.
But I wanted to call out that there is a year rich history there
of people experimenting and trying to build things and looking at the different approaches,
so specifically with like say event machine and ACIN. I think one of the
challenges with the event machine is that you're event machine is written from the ground
up without really thinking about compatibility with existing Ruby interfaces. I think that would
be the biggest criticism I could make the event machine. So when you build
an application that uses event machine, you can't use normal Ruby io. You
have to use event machines custom rappers classes to deal with the vent driven IO.
And i'd like I think for TCP you get a class instance which has
methods that get called back when data is available, and I think for UDIPS
that's similarly a little different. And for things like sleep or timers, all
of these things that all event machines specific APIs. So I suppose to compare
that with a sync well with acinc one point one point x, because we
were kind of in the same boat. We made rappers for everything. So
there's acnc io, which is rappers for Ruby's native io. Acinc itself provides
rappers for things like sleeping, but there's other things which aren't rapped, like
DNS resolution and ACINC one point x process waiting on processes. There's all these
like different things that can cause an application to block and that we want to
kind of lift into the event Look, so when I built ACNC one one
one point x, I went to mats and that was the prototype. It's
like, look, Matt's this, this works. People have done this before.
To take it to the next level, what we need is actually hooks
inside the Ruby virtual machine so that when Ruby itself tries to do a blocking
operation, we can hoist that into the event loop. And it has to
happen at the core of Ruby. It can't be a rapper that sits on
the outside, because the problem with a rapper is it as soon as you
start using an existing application or existing code that uses native Ruby io that doesn't
use the rappers, and so it will block, and so you can't.
It's sort of a compatibility thing. So event machine sort of suffers from that
compatibility, I think. And so while event machine itself is generally quite okay
and was I would like to make an assertion that I think most event loops
are roughly the same performance as every other event loop. I don't unless you
massively mess up the implementation. Event loops are largely on the same level of
perform moments. There's very few things you can sort of do to bet something
black ten dimes faster an event loop. It's all going through the same operating
system interface is roughly speaking, and there's a few choices you get to make
and how you organize the user facing parts. So but but there was one
other issue that I had with event event Machine when I actually tried to use
it, was that it would crash a lot, and it didn't support IPv
SIS or IPv six would cause it to crash or like something in the pack.
And I think one of the one of the problems with a lot of
the existing like never Block and Celluloid and event Machine and whatnot was that maintainers
tried to bite off too much of the like the problem in one go,
and I think that made it hard to maintain or even really specify the nature
of what these the problem these livers were trying to solve. And the problem
that that got to burg and event Machine was trying to reinvent every units interface
under the sun, because it was trying to make them all non blocking,
right, and it's just really hard for one person to do that. So
another point of comparison is with ASYNC, especially ACINC one point, I was
really really specific on what I wanted to achieve and what I wanted the interface
to look like. And I got from ACNC prototype to ACINK one release in
like three months, and I was like, this is one of the most
important things for users is they have a solid foundation that you say, hey,
this is this is this is what it's going to look like for the
rest of eternity. You can build on top of this without coming back in
six months and having everything changed or you know, not working or so complicated
that we don't know how it's supposed to work, or there's a lot of
criticisms I could I could shout, I suppose, and that you know,
it's it's not so much that that software engineers working on these problems were like
better or anything. It's just more like the problem can be extremely complex if
you don't compartmentalize, I suppose. So the second part of your question was
how does Thin and Falcon differ? And so I think when you look at
a server like thin that's event driven thin, I guess in some ways you
could say Thin was pioneering because it it introduced in the roomy world when you
have a web server. We had like an intermediate lyric called RACK. Yeah,
it's a gem which provides the bridge between a web server and a web
application, and it provides a common interface based on the CGI specification or yeah,
some some sort of like hybridized vision of the CGI mashed up with a
bunch of modern stuff. Yeah. Mark Andre and I talked a bunch about
that in the interview we did with him. So fantastic and so thin kind
of pioneered what concurrency for a web like, what the interface for a concurrency
might look like to a web application. And I think this was something which
it feeds into the It feeds into the whole RACK three upgrade that we did
over the past like three or four years. So the CGI model that we
use for a long time was just request response. Here's a request that comes
in, has some here, there's a payload, whatever, and then we're
going to make a response and send that bag out of the wire. And
that doesn't really work for things like web socuits or if you have three hundred
gigabytes of CSP you want to stream down the wire, because you can't really
reasonably buffer three hundred gigabytes of CSP and so reg RECK two did not provide
any mechanism really for the kind of concurrency that Thin was trying to implement.
And I think Thin pioneered what some of those things should look like, and
so we I don't want to say we took them whole say, but we
took the general concepts plus my own feeling on streaming, and we pushed that
into REP three. So RAC three has a proper model, a standardized model
for streaming requests and responses. That means when the request comes in, you
can incrementally read what the client is supplying, and when you write the request
back, you can incrementally write the response back out to the client. And
this works for things like web sockets like perma on. RECK three supports web
sockets out of the box on a on a request thread. And so this
happened at the same time that I built Falcon, and so Falcon informed what
RECKS interfaces should look like. And I think so Thin and Thin pioneered those
interfaces or the nature of some of those interfaces, and then we took that
and we looked at When I was building Falcon, I was like, how
do we actually do this in a way that can work across all web servers,
and so we kind of extracted that knowledge standardized in RACK that too a
couple of years actually, like I'm not even joking, it was literally a
couple of years to figure out what they were supposed to look like and get
a release. And so Falcon basically evolves some of the conceptual things that Thin
as an event driven bob server does. And the one other point is that
I'll draw back. I'll go back to comparability, which is when you run
an application on THIN and it uses like say native io that will block THIN.
So there's there's operations you can do in THIN that will be event driven,
and there's operations you can do in THIN that won't be. And I
think things like emsynchrony, which try and provide the transparent rappers, may help
someone, but it's still not guarantee that you're going to have like the really
good, good experience with Thin with a S two and Falcon, because you
have that interface right at the heart of Ruby, intercepting all those blocking operations
like waiting on a process, child process, DNS, resolution, reading and
writing from sockets, sleeping and timers. That kind of stuff. When you
run an application on Falcon it becomes transparent and concurrent. That makes some extent
as possible on that on that particular implementation of Ruby. So it's it's kind
of hard to say what is the difference, but but they fundamentally in a
nutshell, would be like compatibility and just general approach to concurrency in the way
it's exposed. Cool, very cool. I see Valentino thinking you have a
question, I asked, Yeah, I did. Uh, So I'm curious,
like, uh, the io event? Uh what ask First of all,
I love the ACYNC logo. I think that's for those that don't know,
it's a little sink with a Ruby coming out of the faucet. Yeah,
that's great, hilarious. Uh, but I guess I'm trying to understand
maybe uh, because I know the fiber schedule that you've made right, ultimately
that's made it into I don't know why version of Ruby three Yeah, three
to one was the first version of Ruby that had a full implementation of most
of the critical hooks. And so which aspect of ACYNC of your acink framework,
Like, is that piece of it? So the io? Yeah,
that's a good question. So when I first built ACYNC. I was,
but let me step back. As a software engineer, I prefer to build
modular components. I find that there was an interesting observation I made when I
was building. I used to work commercially on C plus plus projects, and
there was observation I made, which was, the C plus plus build system
is so complex in general that people would they'd build one package and then they'd
be like, Oh, there's so much work to build a package of stuff.
I'm just going to end water this package, and so one package grow
bigger and bigger and bigger. Yeah, with like instead of having small libraries
that could work together, you'd have things like qut or there's a whole bunch
of like C plus plus frameworks that the just go from from you to I
all the way through to like database and networking or something, and it's like
and everything in between clude like their own implementation is smart point is and just
like the whole the whole everything, And it was just as a commercial software
engineer working on C plus plus projects, I just found this insanely frustrating because
you're pulling one dependency for one little tiny piece and me to get the whole
kitchen sing when I moved to Ruby and started working in a more commercial sense
in and open source as well, It's like, wow, this is great.
It's like so easy to make a package like a JAM. And so
I've always had this mental model that like the overhead of electronic package upsource code
is like kind of inversely proportional. It is there right to like the size
of packages. Yeah, maybe I got that backwards, but anyway, like
the harder it is to make packages, the worse the packages become in terms
of scope and like compatibility and everything. So I was really inspired by Ruby
gems and how simple Rubygens makes it to build things. So when I built
Acing and the things that came before, I always felt like I want to
build small packages that work together, the compatible, composable even years. And
the reason why is to avoid that multiplicative complexity that comes out of like huge
code bases. And it's even hard to understand. You go to a code
basis one hundred thousand lines of code and you're like, where do I even
start with us, like trying to understand what problem the person was trying to
solve and what they were thinking when they were solving it. So ACING,
you're talking about just just to back up for a second, you're talking about
something like if I wanted to use active record, requiring me to pull in
rails to use active record as opposed to just having active record as its own
little Yeah. I think if you go to look at yeah, if you
go and look at other like languages, you'll find that in order to use
like active record and whatever language you look like, it was C plus plus.
Let me just pull that example again. You wouldn't just be pulling in
like a database, a debt. You'd be pulling in like a whole.
It'd be pulling in like everything. Yeah, everything. Yeah, go and
find like something which only does databases in an ergonomic way, right, yeah,
and yeah, like like maybe Burst is another good example. I know
that bursts can be used independently, but we pulled Burst into projects and it
would add like thirty minutes to the compiled time and like thirty gigabytes of optimber
storage just for the like intermediate files. This is like crazy anyway. So
with ACYNC and gyms that came before, in gyms that have come since,
I always felt strongly I've got to compartmentalize this so it's easy for people to
understand. And actually it was interesting because I've had that feedback from people people
look at the cone that this is easy to understand, like I get it,
and I learned a lot from your current So I'm always hapy to get
that feedback. ACINK one because it was really the proof of concept. It
used an existing gym called n io FAR, which is an event loop that
was especially used by rails now inside action cable. But the FAR is just
an event loop interface. It uses lib ev under the hood, and it
provides non blocking IO for Ruby. And it's the strongest thing about that gem
is just how robust and long lasting it is. It's been around forever.
We have very few bad reports. It's it's solid airs like it's just been
It's a workhourse of I. But it doesn't do anything else apart from io
non blocking IO. So it only does that part of the problem because it's
the problem I was going to solve an ACNC one, you know, as
a proof of concept. That's what we use. So ACYNC draws on n
OO for is the back end, and it provides non blocking IO and you
can build other primitives on top of non blocking IO, like if you want
to do process weight and all you've got is non blocking IO. What you
do is you make it through it. You start your process on there,
and then when the process has done, you have a pipe like a notification
pipe you write on and the main event look was just waiting on that there
end of that pipe, and so that's when you know the process is finished
running. So there are there are ways you can achieve. You can compose
that together to achieve more complex behavior. And ACNC two because that wasn't there
was more about we've showing the proof of concept. Now it's all about performance.
So ACINC one ACINK two actually exactly the same or very very similar interface
like from the user developing point of view, but the back end is completely
different. And so the iow event Gym provides an event selector similar too for
hour, but it's much more comprehensive and it's quite quite the challenge to implement
that across all platforms efficiently and support the wide range of features that we wanted
to support non block and like wedding on processes on BSD versus make owaves versus
Linux. It's all a little different. And so the IOWA event Gym is
where we multiplex out to the different operating system interfaces to do things as officially
as possible. Does that answer your question someone, Yeah, I think so.
I guess that makes I guess I'm trying to find the like upstream Ruby
aspect of it and what what you're bringing to like where where does the fiber
schedule itself like get involved in that stack? Yeah? Okay, So the
IDOW event gym provides a class called selector, and the selector class provides a
lot of the low level interfaces for waiting on IO, so waiting for something
to be readable or reading from something, waiting for a process to become,
to finish, and so provisably is like low level implementations. And then async
acinc has a scheduler, and a scheduler has a selector. So the selector
is something which I suppose you call it a sleep because it's selecting things that
are ready to go, and the scheduler is basically saying what's ready and then
doing that stuff and scheduling the fibers to resume execution. So where the fiber
scheduler interface comes into play is when you start an acinc block. At the
top of that block, the acink scheduler that's allocated as part of that block
will register itself with Ruby as the fiber scheduler, and so then when you
do operations inside that block, those operations will be redirected to that particular scheduler,
which will then decide do I need to delegate this to the event of
the selector and wait for something to happen or whatnot? Gotcha? So,
I mean that's pretty cool. Have you found, like, uh that certain
platforms like are are more efficient at doing like selecting, or or like the
scheduler is like more efficient in certain platforms or do you not like even bother
like measuring at that level? No, if you have a lot of time,
it's a really fascinating problem area. Gosh. Uh. So there's a
couple of main implementations. On Linux, you have EPOLE in irgurin on met
n bs do you have cake here? And on Windows, which we don't
really support very well, we have io c P. And then for other
platforms we just used we defer to Ruby's internal select which is often implemented on
top of Pole, but not always. So give you like a very tangible
example of like where something is very different but this is more of interface thing
than an operating system difference. And actually, I'm not sure, not sure
if this is still true today, because it's not something I readily go and
check. But the select interface on Unix can only handle up to file descripts
one or two four. If you have more than one twenty four file descripts
in your process, select will break. And the reason for this is because,
at least my understanding at the time looked at this, Select users a
bit set, so it literally uses like a piece of binary data and it
flips the bits there one depending on whether you're waiting on that. And the
challenge with there is every iteration on the event loop you're providing. You have
to construct this bit set like hey, here's all the things I'm interested in
up to like whatever, and poll is the same, it's syste list,
and then you supply it to operating system, and the operating system is like
going to go through that list one at a time and say, hey,
this is ready, this is not, this is ready, this is not.
And so if you have like say five connections, that's five things operating
systems to do it. But if you have like five hundred thousand connections,
there's five hundred thousand things that our process semes to do every time it goes
through that like low iteration to process like events. And so the reason why
I mentioned this is because this is wh sort of have a fundamental performance difference
in like the APIs. The most primitive APIs are linearly proportional to the number
of like connections you have in terms of like actual individual operation to find out
what's ready and what's not. But its people. People. People found that
was a problem, Like people were trying to build high performance web servers and
and dns and and whatever else and quickly range like limitation of this interface for
a ventrom and io, and so we ended up with things like poll or
epole or cake where instead of giving that whole list to the operating system every
single time you want to check for readiness, what you do instead is when
you monitoring a file descript or like when you're monitoring something like a network connection
or a web request or whatever, is their data available. What you do
is you register that into the operator and say, hey, when this thing
becomes readable, you let me know. And then when you go through the
event loop, instead of like providing that huge list, you basically say like,
yeah, I told you before, like if this thing comes readily,
you know, and you basically say, is it ready? Now, tell
me tell me if something became ready. And so we turn it into sort
of like instead of every iteration of the event being proportional to the number of
connections, is now just sort of a constant time operation basically proportioned or the
number of ready connections, because you're going to get back a list that's the
same size as a number of connections that have actions to occur. And honestly,
that's pretty much what you hope for. And so KQ and Epole Earth
work like that, and they're considered really the gold standards I suppose for high
performance event driven networking. The biggest problem with those interfaces is that they are
really good to readiness based notifications. Now, basically what that means is when
you have a socket and data is coming across the network. When the data
comes into that socket, the socket is now ready to be read and you're
getting notifications hey there's data available. You can read the request or whatever.
If you try and extend that to the file system, we have files on
disk. A file on disc is always readable. You can always read the
data. It's not reading the data. You're not waiting for the hard drive
to like, you know, spin it around and get to that point.
At the code level. What you're waiting for is the data to come off
the disk and end up in the buffer somewhere that you can access. And
that's I don't want to say it's the slow park, because it's pretty fast,
but like you know, that's the part where you're waiting. And so
the readiness based notification kind of breaks there because it's there's no easy way for
you using e poll or kqu to basically say hey, I want you to
go and read this data and then let me know when it's available to be
read, like what's the like, there's no API for them, and so
there was an original attempt to solve this called like aio or acinc io,
like at the Linux, and I think there was just considered really bad.
Like everything I've read about it's basically just don't use it, and I've not
personally used it, so I don't really want to say like it's it's horrendous,
but I think when I last read about it, what I read was
that a lot of it was emulated and lives and was basically just mapping back
to sequential reads and writes or something. So what what we The evolution of
this API epole is one that supports not just readiness notifications, one that also
supports completion based notifications. There's two kinds of notifications. Readiness is when something
is ready to start, and completion is when something is done executing. And
so when you read data from a disk, you're not interested in waiting for
the readable discs always readable. You can always issue a read request on a
disc and like a socket where if the data is not there, able to
stop your wait forever until the data comes in. Completion base is when the
data is ready to be used. And so Windows has IOCP and Linux recently
experimented with some a good iou ring which is now gaining more traction. And
in fact, I think io your Ring was so good. It was very
funny when it's actually copied it and now when it has their own io your
ring, which actually I tried to use it and it didn't. It was
like horrendous. I couldn't figure it it out, how to get it to
work at all. So so in a nutshell, there's a variety of interfaces.
Fundamentally, what it comes down to is readiness, burst completion and having
those different support for those different events. So when I event jam, we
do support you RING. It's actually the default on LINEX now if you have
an up to date colonel, and it will actually use where possible completion based
notifications for file system and sometimes network I depending on the circumstance. And so
that's actually funnily enough, it's not a huge performance one. As I mentioned
before, event loops much of a muchness. You're beholden to so many figures
outside of your control. And as you asked, do I measure this stuff?
Yes, and I owe you RING actually there when you really get down
to it, when you really start trying to like micro optimize some of these
things, there are some incredibly different, like challenging insights that you derived from
from benching in micro optimization that I suppose the kind of disappointing in a way
as the engineers, you know, when you're trying to actually get to that
level and then you finally realize, oh, even though I did all of
this, I ran into this wall here that I kind of overcome. That
can be a bit frustrating and I arguing, while it brings a lot to
the table, still has a few things like that, and to me,
like she is quite fascinating and what we do next so cool. Yeah,
hey, there, this is Charles Maxwood. I'm excited because I wanted to
let you know about this thing that I pulled together that I had just I've
been dying to have this for years and I never felt like I could,
and then I just realized that there's no reason why I can't. So I'm
putting together a book club and we're going to read development focused books, career
books, you know, technical books, whatever. The first book that we're
going to do is going to be Clean Architecture by Uncle Bob Martin. If
you're not familiar with clean code or some of the other stuff that Bob has
done, check that out. And I've also talked to him on the Clean
Coders podcast, which is on top end devs. But yeah, we're going
to get on He's going to show up to some of our meetings, and
what I'm thinking is we'll probably have like five or six people part of the
conversation along with Bob and I at the same time, and we'll just so
somebody can come on, they can ask their question, and then we'll just
rotate people through, so we'll mute one person, unmute another person when it's
their turn to come on and be part of the discussion. So we'll do
that for like an hour hour and a half. And then the other part
of it that I'm putting together is just kind of a meet and greet gather
area on gather Town. And so after the meetup and the call, we
we'll do as we'll all go over to gather Town and you can just log
in, walk up to a group and have a conversation, and that way
we can all kind of get to know each other and make friends and get
to know people across the world. One thing that I'm finding is that,
yeah, the meetups are starting to come back, but a lot of people
don't have the opportunity to go to a meetup and I really want to meet
you guys and talk to you. Gonna put all that together. It'll all
be part of that book club. You can go to topendev dot com slash
book Club to be part of it, and I'm looking forward to seeing you
there. The first book club meeting will be in December, the beginning of
December. We're starting the first week of December, and you'll also be part
of the conversation about which book we do next. I have one in mind,
but I want to see where everybody's at. So there you go.
So I kind of want to change the topic a little bit, because I
mean a lot of this stuff is fascinating to understand how things work under the
hood, but these are not things that at least in my there's not things
that I plan on touching, right. It's just like fair enough, Okay,
I know that there are little gnomes in my computer that are banging on
this stuff, right, and you're teaching the nomes how to bang on other
stuff, right, And so I'm just gonna run my rails app or my
Ruby you know, Ruby script or whatever on my machine and it's gonna it's
gonna work its magic. So if we come up a few levels too,
kind of the level where I'm usually programming, right, where I'm either writing
a script that does a bunch of things right, and so then I have
the the a sync non blocking io stuff that's interesting or you know things like
that, where do you see people using a sync in Yeah, really good
question. So it's interesting sometimes I hear about like big companies using acing,
they never really divulge much information, so it's fascinating to learn about different use
cases. I know, I want to play buzzword bingo with my projects too.
I'm using aim blockchain and you know, throw in a little bit of
this and a little bit of that. I mean, oh, I can't
tell you what I'm working on. It's stealth mode. Yeah, absolutely,
sir. Where I think Acinc really shines right now is in applications that are
io bound. And it's especially true for things like API servers, proxy servers,
anything like proxy gateways. So if you if you have we just had
someone recently talked to this. They migrated an application from I guess Perma to
Falcon and acing HP Faraday with a few minor changes because I think the acing
HP fairy supports persistent connections by the faults of the book keeping in the application
level. And I think they saw like half the latency, twice the throughput
and have their running costs and so wow, okay, this is the kind
of like and so there was an API gateway if I recall correctly, and
so this is the kind of thing where request comes in and it's basically just
getting proxy through like a different system. And I've seen like a variety of
people with these types of systems in production having great success with the event driven
model. And I think a lot of these people when I when I talk
to them, they don't have to make many changes their application. Which was
one of my original goals was to kind of transparently try and go in there
and make all of those operations non blocking. But sometimes applications do explicitly want
to opt into concurrency, Like sometimes concurrency is a performance thing, and sometimes
concurrency is actually a functional requirement of an application, And I think it's important
to be aware of those two distinctions. So where concurrency is about performance is
if you have Falcon and it's just doing like net HTDP is an APR gateway
you can run, like if you run that on Falcon versus Perma, you'll
get better through put on Falcon without any changes, So you improve your performance,
but there's no actual change to your application behavior or anything like that.
There are also situations where you might be like, hey, I have a
deadline. Let's say you have Let's say you have some data that comes in
and you want to sell it to the highest better, as you need to
know who's going to be the highest better and you're never limited maybe the data.
The value of the data decreases over time, maybe by the second,
and so in that scenario, what you want is you want concurrency because you
want to talk to as many people who are going to pay for the data,
find out who's going to pay the most, probably have a deadline on
when they're going to reply by, so you need to have strong guarantees around
the the operational timing of this of all these requests you're fanning out, and
so Acon can do this too. This is where you probably use like a
fan out mat projuice style approach where you basically, hey, I have like
all these you know, providers I want to talk to, I have the
data that comes in. I want to fan it all out as quickly as
possible over a five second deadline or a ten scin deadline. If they didn't
reply by, then see you later and then go through and figure who's going
to pay the most, and then finally ship the data off to them or
something like that. And so we see use cases like this as well,
where people are using concurrency at the application level to achieve things that not be
easily possible using other approaches. And when I say easy, like look if
I if I'm completely frank, like, of course there are other ways to
achieve some Ruby like threads and maybe even rectors. I feel lucky that works
for you, But I just I wouldn't call them like easy. And I've
certainly had experienced with like other Ruby gems which without a foundation, like asaying,
without kind of like a generic foundation. You have like gems like uh
typheus, which is an HP gem which can do multiple requests. But then
you have like other gems which do the same thing, but they're not compatible
because they all use different like event driven foundations, and so they don't work.
They're not competible with the server. They're not comparedible with each other.
So if you start from a mix of stuff together, which I've seen,
it just ends up like a huge disaster. So I think that's the value
proposition of ACE. There's it's a foundation on which if everyone or you know
and she's it's the fibers schedule, which is the common in defense acin what
is it saying like acink is dead, Long live ACYNC or long live the
fiber schedule. Acink is a great user developer experience in my opinion, But
if you're building a library, you should target the fiber scheduler, not ac
unless you really want to like well, you can choose, of course.
But and so when you run your WAB application on Falcon, not only should
you see improved concurrence I concurrency, so database queries will run in theory like
at the same time, if you have like a high latency query, like
that's not uncommon, then you forgot to put an index. It won't solve
their performance of an individual request, but it will improve the concurrency of the
whole application to the extent possible. But where it gets really interesting is when
you start adopting that model in your application. Yeah, I'm curious about that,
Like, I mean, it's especially now that you know the Ruby world
is still like very much dominant by Rael's ecosystem. Uh. And then so
there have been some more I mean I'm curious because Reels was not always like
you know, runn able on Falcon right, yeah, yeah, yeah,
what was that story? Like what were the challenges there? And like is
it okay? Now I don't normally tell the story in public because I don't
know, I'm gonna like upset, but I think it's about time of talent.
So when I originally went, hang on, let me get some popcorn.
Yeah, look, this is no criticism of anybody. It's moreest a
funny story. And it's probably fair enough that everyone had the opinions they did
at the time and still and still do it to some extent. But it's
also a challenge for me. I suppose. Uh when I first went to
the Rails people and said, hey, you know, can we support as
you know, Falcon or this concurrency stuff. And I didn't really get like
a strong positive reaction. I didn't get like a hugely negative one. I
mean, not everyone looks at it through the same lens that I do.
And that's actually quite good. You know, diversity is often a good thing,
especially in software engineering. Well actually I'm not sure about that, buts
versus faces. Yeah, anyway, so I didn't want to push too hard
on that, and you know, cause more contention, I suppose. And
so it was around the time when I was building Falcon, I thought,
okay, well, actually it's not Rails. It's not The problem is not
Rails. The problem is actually Rack and it wasn't really a problem. RACK
was not evolving at all, and it certainly wasn't evolving in a way that
would support streaming requests and responses and whatnot. And so when I first started
working on RACK, I don't know, I think there were like hundreds of
open issues, like it was just a project. They had been stagnating unfortunately.
So I went when I literally closed I don't know, like a couple
maybe a couple of hundred issues, pull request stuff like that. Was it
was a lot of work, and I wrote in Jeremy Evans, who's amazing,
and gosh, I would like, let me let me say I think
I think we're a great team. And I don't want to like take creator
because I think we're equally like being instrumental with the whole thing. But I
want to say he's a great partner, great great, a great, great
teammate in this open source maintenance. And and so because I felt like it
wasn't too much, it wasn't really worth trying to push you oard on rails.
So I went to RAG and I sort of solved all the problems there,
and then we finally released RACK three. And the great thing was I
only needed to get consensus between me, Aaron, and Jeremy to Rails and
said, hey, Rails, here's RECK three and here's how it works.
And so then we made a bunch of poor requests of Rails to make it
compatible. And that was basically objective truth at that point. So with Rails,
Rails seven point one, with all I think there was like maybe ten
or twenty poor requests that I made now supports RACK three, which means that
Rails supports streaming requests and responses. It means you can drop a web socket
in the middle of a Rails controller and have it work. And if you
run on Falcon you get a ventriven currency with that as well, which is
pretty neat. So the challenges with Rails have been extensive. Rails has I
like to use the word ossified ossified around the request per three or request per
process and going in there with like requests per five it was kind of like
and so there were a lot of assumptions that we completely destroyed. And so
now we hear something called that one of the most critical pieces was done by
uh I think sorry mispronounces like Jean Bossier. Jean Bossier. He implemented the
I think he implemented isolated execution state, or maybe it was someone else I
can't remember. Actually I apologize to whoever wanted that, but it was a
really fundamental feature two, basically configuring RAILS two instead of storing its request date
per thread, which on Falcon every request runs on the same thread, so
of course if you're sharing your request date per thread, you're sharing your request
date with every other request at the same time. Instead, it isolates it
to per fiber, and then that change has to percolate out across all the
different systems and RAILS. The biggest one is age of Record, which is
also the biggest source of database sorry IR latency and lots of applications, and
so right now there's a pull request to address address some of the issues that
we've identified with the performance of age of Record on a fiber based server.
So I think RAILS seven point one is compatible like fully compatible with with with
Falcon, and RAILS eight will make it even better, and I think we're
on track to seeing uh much. Let me just say that I think RAILS
eight will just work, and it will just work really well. Nice.
So on a related note, where was they gonna go oh, I remember,
I'll let Valentino ask this question and I'll ask my question. Sorry.
Yeah, I was just gonna say, like, I'm not gonna lie.
When I first saw like Rail's database, you know, do it later kind
of you know a sync uh. I was very I mean having somebody just
like sprinkle those around everywhere in his current in the state they released it at
it seemed like it was like a little too much magic for what it was
doing at the time. And I now I feel like a little better now
now that you've gone through the state of things. I know we're still not
quite there to just like, Okay, everything's concurrency in rails now, I
know that's not true, but yeah, I want to just call it a
little distinction. Dan, So you've mentioned a feature in Rails called load as
called I think, Yeah, I'm a little disappointed they chose this name and
convention because essentially load and threat it's not it's got nothing to do with acinc
the like the gym that I created. And while it might solve some problems,
I actually had feedback from some people who tried out on their applications and
said performance was either the same or worse, and that it actually was hard
to know when it should be used. So I think that the value of
load ACYNC in rails as it stands today where it does it does a database
career in a background through it is when you can stack up several database quers
that are slow and have them running parallel. That's that's the key advantage.
But the problem is there's only so far you can push that. I suppose
even if Falcon, there's only so far you can push paralysm, concurrency and
h when you parallelize operations instead of having the linear some of the total time
you have you state them to get the time is the slowest operation. But
not that I suppose in the real world use case, not that many people
are stacking up whereas like that annoying. When to do it and where to
do it is the challenge, And so with Falcon we still essentially either do
linear or if you explicitly opt and you can do the same thing like multiple
dard base careers in parallel. But it's not just the individual request that if
you run that in PERMA, you're still tying up the entire request threat and
Falcon that whole request will just get set in the background until the data and
the dard base comes in and then it will get resumed. So maybe in
summary, like the performance characteristics of load ACNC and RAILS as it stands today,
it's not really easy to have an intuition about where it makes sense.
And that that to me, like it comes back to what I've said really
at the start, which was building the good developer experience or building the interface
which is kind of intuitive and makes sense, is really like fundamental with this
whole problem because concurrency is hard enough without trying to get used to think about
these issues and trying to figure out where this makes sense to where it doesn't
make sense. Yeah, that makes sense. I'm gonna push us to another
topic here really quickly. It's it's kind of related to some of this stuff
where you I think Valentino actually brought it up before the show and then you
know, I asked you about it heading in, and that is he said
something about you building Falcon into a platform that's more than just a web server.
Where you started to discuss that, you know, before I stopped and
said let's talk about this on the show. It sounded very interesting. So
do you want to kind of plug into that and explain to people what you're
looking to make Falcon into. Sorry, just replying to someone. It's the
greatest keyboard, right Cherry Browns. Look. So when I first married Falcon
as a proof of concept, I kind of squashed a lot of stuff into
it, including uh so, there was a gem that there was a client
HP and serve a gym called acinc HGP. That gem supports HP one HB
two today and hopefully in the future supports HDV three. I've been working on
it, but it's quite HD three is like probably the most insanely complicated standard
ever tried to deal with. So Falcon was kind of an adapter. I
think h GDP has has a has a. There's a gym called Protocol h
GDP which provides a generic request and response smandic objects. So like the head
is the body, status code, the version that kind of the stuff that's
the same across all versions of h GDP, and then acinc hg B takes
that and puts it into a makes the request and response running an asynchronous task,
so each individual request or response is is is operating concurrently. And then
what Falcon did originally was adapt rack applications into ACNC HTP server compatible interface and
that that was actually non trivial because there's things like rack hijack and like all
the head mapping stuff and dealing with response bodies that is quite there's like quite
a few complexities in that to map a RAC application to a straightforward HTP interface,
And after a while I just thought this is something that I actually want
to use in a more generic sense, like mapping IRAQ application to an ACINC
HP server is not something that's Falcon specific, and Falcon became more about So
there's a gem that does is called Protocol dash Rack, and Protocol dash Rack
provides all the mappings between acinc HVAL, protoco HTP, and RACK. So
you can take an incoming request that that follows that very simple semantic format and
map it into like a RAC object and then you can map it back again.
And it does all the mappings for things like handling streaming request and responses.
So if you throw a websuck at at it will work correctly, which
is kind of kind of important. So Falcon got split up into pieces,
and so what Falcon does today is Falcon is kind of an application container,
and what that means is there's a gem called acinc Container, and acin container
lets you do multi threaded, multi process or hybrid or various other ways of
deploying and application and scaling that application. And what Falcon does is it dis
coordinates basically that container for like rolling restarts, blue green deployments, these kinds
of like things. And it has a configuration which basically just says, hey,
I want you to host this RACK application on port whatever, and so
you can run any application in there. It doesn't have to be a RANK
application. You can actually run a native HP server compatible interface application and Falcon
will host that you use you host multiple applications in one instance if you want.
So it's just basically a container now for hosting applications and all individual pieces
are just connected together. And so where I think this goes next is I
quite like to see us simplify like rails deployment. This is we like put
a goal to it. It would be simplifying rails deployment. And I think
there's been a lot of work in this area, but it's still quite challenging.
Like you need a database, probably need reddis you probably need background job
runners, you probably need obviously a web server usually sometimes you get other things
running in the background there, and we've had things like what's that, what's
there a tool called that starts multiple processes. Gosh, I for get,
there's there's there's a couple of gyms be full coordinate all these processes for you.
But I wanted like that, yeah, foreman, that's the one.
Yeah, And so I've used that in the past and it works okay.
But I felt like it's still quite difficult to deploy a server, and so
what I wanted to I would have to like have a self contained application,
so Falcon application that includes like a job server, and you basically go,
here's my hardware, go and run this, and you have to be so
nice. I think even action cable can be quite tricky to deploy, you
know, like with action cable often you have like any cable, or you
have Perma that's the dedicated it's a PERMA running on a different port. It's
just like all these like funny, tricky things that have fallen out of the
assumptions we've made about how things are going to be deployed. And I feel
like if we just step back and go, hey, but what problem we
really going to solve here? Falcon can better address those by by exposed and
kind of this can you know, application host base model. But you basically
wanted a job sere and a web server and disserve de server, and I'm
just gonna start it all up and my applications running. Yeah, in fact,
for my development stuff, I started out with the tailwind cssgem for rails.
I guess it's tailwind CSS tesh rails, right, And so when you
install it, it installs the bin dev executable, which effectively calls out to
foreman and says, hey, run the tailwind watcher alongside the web server,
right. And so then as I've added in full tech search and things like
that, right now, it's it spins up the full text search engine and
right, all the things that have to go into all of that stuff.
And so anyway, just kind of throwing that all together, it'd be really
nice to be able to deploy that way, because yeah, when I deploy,
it's okay, and I'm using camal and so it's I need an accessory
for this and an accessory for this, and then I need two app servers.
One of them is the app app server and the other one's the job
server, right, And so it orchestra orchestrates like six or seven different Docker
containers across three or four servers to do all the things that I need.
And yeah, it would be beautiful to just be able to run all or
most of that under a Hey I've got this application that runs like this,
and then sure, maybe I have a caddy or traffic load balancer out there
that I have to manage separately. But yeah, anyway, I think I
think I've made things too complicated. Well, so David dh when he gave
his Rails World his Rails World keynote, and he was talking about all the
different things that are going into rails, and you know, he talked about,
hey, we got this, and we got this, and we got
this, and then specifically he got into the asset management for Rails and what
he said was, we picked up webpack and webpacker because it was kind of
the most comprehensive way to do it and it did everything that we wanted,
but it was complicated and gross and hard to use, right, and so
what then, what he pointed out was, but we had to take that
step in order to get to where we got to with import maps and h
prop shaft and so when I look at it, it's like, yeah,
we've kind of done things in a way that is not exactly the most friendly
way. But I think what it's done is it's kind of given us the
tools for Okay, we know that we generally need all these things now and
we know how to run them all. So yeah, unify the interface,
I think, but it's an essential step to getting where we are. Yeah,
to your point, I think to know the happi path, you have
to know the unhappi path. Yeah. Well, sometimes you get lucky and
you can just happy path your way through it. But yeah, but then
you don't know. Then you don't really know how happy you're like yeah,
because you didn't really experience the pain of like doing it. Yeah. I
mean that's kind of that's kind of the like the negative of rails as a
framework, right as it provides all this magic, and you know, if
you specialize in knowing the feature, uh, then it you know, then
you need to know, right, like otherwise forget about it. Like yeah,
but like okay, well, if you run into like an edge case
you know, well, and the person that is expert like is unavailable,
then like you're spinning your wheels trying to figure out how it all works.
I mean, I want to talk to the specific point. A long time
ago, I did a jet of C development with airports like frameworks, and
they were there was no source card. If you're like in his table view
didn't work correctly, there was no way you'd be able to figure out like
why the thing was rendering wrong or why the column was in the wrong place
because you put a brake point and it would just there's nowhere else to go.
And I really want to call out, like how amazing Ruby and Rails
is. I mean, of course open source projects are all similar in this
regard. I suppose it's part of the definition of having the source available,
but it's just so refreshing if you've had that experience that pain to be able
to go into the source code all the way down to like the interpreter.
I mean occasionally I do find bugs and I'm digging in the interpreter, putting
like estate it's going to figure out, like what's going on. We're so
lucky to like to have that, and I just I want to call it
out because like maybe people don't realize, like if you've all you've ever done
is use RAILS and frames with all the source code is available. You may
not have experienced the level of pain that comes from using closed sourced frameworks or
lib resort or whatever systems, and it can be extremely painful when you're trying
to debug an issue, Like I'm talking like multiple weeks with multiple engineers trying
to like I get things out. So we're extremely lucky with Rails in Nate
regard, Yep. Absolutely, Well, we're kind of getting towards the end
of our scheduled time as far as usually picks take up a little bit of
time, so really quickly if people want to, can we can we get
to one quick thing because I just saw that Samuel released like a spike on
a sync job, which is like one of the most requested like things I've
been waiting for, is like this the surface. Do I just get a
quick like THELDR of what that is and maybe how people could get involved.
So I think Rails has done a pretty good job of shaping out interface for
job execution, and I think Mike did a great job of creating Sidekick,
and I think we've converged on what it looks like now is a user interface
application developers, what's you know. Mike's work was really pioneering, I think
in lots of ways, and acinc job well, sidekick uses multiple threads usually
for executing multiple jobs, which which is perfectly acceptable, and I think headlights
to also use reactors if possible. I think that's still a way out.
But acinc job is basically runs on a similar principle users riddus. I'm hoping
to also add like a database back end as well at some point, maybe
squl light or just generic database layer, and then it basically it's your schedule
and execute jobs. And so my goal is to have this provide so on
the client side it will provide like an active job adapter, and they will
probably be the main most common use case, I would say. And then
on the back end it will just use a sync and probably I'll make it
very easy to spin up as part of a Falcon application, so you might
have basically seeing your Falcon configuration, a weir application and a bit of jobs
ever and and have that just x Q and coordinate as efficiently as possible.
So yeah, acinc job is something I've been meaning to work on for a
long time. I just didn't really have the band with for it, but
the current spike is looking quite good, like it's it's I think ACYNC maybe
to give an interesting context, I often work on the library of ACYNC,
so I'm not not that often like a consumer of ACYNC. But with acinc
job, I was kind of a consumer of ACNCY. Like you know,
there was a very fundamental part of a job and so I had like that
good experience that I was trying to you know, from the other side.
It was really straightforward to write the code. Radis just worked. It was
easy to do like quite complex things with fratis, like have a heartbeat a
job server with a heartbeat, which then recovers jobs if the server dies.
So a bunch of this functionality it was all done instead of like you know,
maybe what one hundred lines of code to code And if you compare that
with I know that Psychic does a lot more, but Psychic has a lot
more lines of code. And I'm a big fan of like list lines of
code, list bugs. So it's really admirable. I think, yeah,
well, I'm looking forward to seeing more progress on that because uh yeah,
I feel like that's the one thing as rails app grows is you try and
figure out how to execute all your jobs faster. Yeah yeah, yeah,
yeah, you guys drop a link to that in the comments. It goes
out to Facebook, YouTube, and Twitch, not Twitter LinkedIn if you're over
there. Awesome, all right, I can do Yeah, it looks like
Valentino dropped it. All right, Well, I'm gonna push this toward picks
and wrapping up the show then. But before we do that, Samuel,
if people want to connect with you, if they have questions or things they
want to do with a SYNC, how do they find you. The best
way to do that is for get hub discussions. I have a personal ge
hub discussion under GitHub slash by aquatics. But if it's ask specific, then
just go and find the projudie and can use the discussion. Okay, there's
a whole bunch of earlier adopters and fantastic open source maintainers and contributors. Perry
will if I'm not available jumping usually and I'd like to me that's amazing.
So yeah, it's the best way to get in touch. And the great
thing about that is me building a knowledge base. So you might want to
do us if you've got a sort of a technical question been doing a search
first might help out as well. Awesome, Well, we'll put a link
to your GitHub in the comments and then yeah, my team can pull them
out and put them in the show notes. Let's go ahead do some picture
real quick. Have you ever wished that you had a group of people that
were just as passionate about writing code as you are? I know I did.
I did that for most of my career. I'd go to the meetups,
I try and create other opportunities, and it was just really hard,
right the meetups. I got some of that, but they were only like
once or twice a month, and it was just really hard to find that
group of people that I connected with and really wanted to talk about code a
lot, right, I mean, I love writing code. I think it's
the best. And so I've decided to create this community and create a worldwide
community that we can all jump in and do it. So we're going to
have two workshops every week. One of those or two of those every month
are going to be Q and A calls right where you can get on you
can ask me or me and another expert questions. The rest of them are
going to be focused on different aspects of career or programming or things like that.
Right, So it'll go anywhere from like deployments and containers all the way
up to managing your four oh one K and negotiating your benefits package. Well,
we'll cover all of it, okay. And then we're also going to
have meetups every month for your particular technology area. So we have shows about
JavaScript, react, angular view and so on. We're going to have meetups
for all of those things. I'm going to revive the freelancer show, so
we'll have one about that, right, so you can get started freelancing or
continue freelancing if that's where you're at. And I'm working on finding authors who
can actually do weekly video tutorials on some thing for ten minutes. This related
again to those technology areas so that you can stay current keep growing. So
if you're interested, go to topendevs dot com slash sign up and you can
get in right now for thirty nine dollars. When we're done, that price
is going to go up to seventy five dollars and the thirty nine dollars price
gets you access to two calls per week. The full price at one hundred
and fifty dollars, which is going to be seventy five dollars over the next
few weeks. That price is going to get you access to all of the
calls and all of the tutorials and everything else that we put out from top
Endevs, along with member pricing for our remote conferences that are coming up next
year. So go check it out topendevs dot com slash sign up Valentino.
Do you have some sure? Uh? So, I love hacking on hardware
in my free time, and I came across this, Uh, somebody made
an open source wearable AI device that uses the Cora AI h embedded system.
Uh. And I'm really Coral, sorry Coral di AI. So I'm really
in. I got a whole set of things that I'm gonna try and use
a Raspberry uh piser or pied Wu and the Coral and fuse them together and
hope that I can like make my own like wearable AI device. Uh.
And so he has a whole project down I forget the name of I'll put
it in the show notes though, but I'm looking forward to building that next
weekend. Very cool. Yeah, I'm gonna throw out a few picks here
myself. The first one is I always do board game pick on the show.
So last night I was hanging with my friends and one of my buddies
bought a new game, and so of course we played it and it was
awesome. It's called fire Tower. Came out in twenty nineteen, two to
four players. We played it with four players, just to put that in
there. We were kind of time limited, and I think it took us
an hour maybe a little more in an hour play it hour and ten hour
and fifteen And that was with us learning to play the game and playing the
game and effectively. The idea is is each player has a tower in one
of the corners of the board, and then there's a wildfire in the middle
of the board, and you take turns. So the wind's blowing in a
particular direction, so you add a flame token to the board in that direction
from any other flame token right has to be next to it. But then
you play a card and so the cards can put out fire, they can
expand the fire, they can change the wind direction, and so the the
the way you win is you take out everybody else's tower, so you move
you you move the fire toward them and away from you. Is kind of
the deal. I I really enjoyed the game. Will also point out that
I won the game by taking out each of my friends one at a time.
When you're eliminated, you are the spirit of the forest, and so
you roll the die for the direction of the the wind, and then you
have different actions you can take. So North, lets you, i think,
put a fire token out, or one of them, lets you change
the direction of the wind one of them. Anyway, so it's it's way
fun. It was a lot of fun and so but it's relatively simple board
game. Geek waits at one point seventy nine, which means very easy casual
game. So I'm I'm digging that that that's it was. It was a
ton of fun, So I'm gonna pick that. If you're in Utah,
I think it might be sold out, but if it's not, I'm going
to salt Con in a couple of weeks, three weeks, and salt Con
is a board game convention in Davis County, so just north of Salt Lake.
So if you want to come play games with me, let me know
you're going, and that'll be fun. I'm heading up with one of these
buddies of mine and anyway, fun, fun, fun. So excited about
that. I also have the Ruby Dev Summit videos up. If you go
to rubydevsummit dot com and you put your email address in, you can get
access to the videos for twenty four hours. They incidentally have also been going
out on the Ruby Rogues feed this week, but I plan on taking them
back off of the feed, and so if you didn't get them, you
didn't get them, and I'm sorry, but just go to the web page
and we'll hook you up. Just trying to think what else. I mean,
mostly just been heads down working on rails clips and Ruby bits and so
if you're looking to learn more Ruby your rail stuff, go check out the
videos there and I'll wrap it there. Samuel, what are your picks?
Sorry, you're going to explain this concept to me. It's okay, So
every show we just picked stuff that we like, so the stuff you're enjoying.
So yeah, so it's a TV show, So another one I could
pick. My wife and I watched once on Netflix, right, that was
a fun series, board games, tech stuff whatever. I've been watching Futurama.
I'm really happy they revived it show. It's slious, such a great
job. Yeah, I suppose what's great about Futurama At least I don't know
about the latest version, you know, the latest season it's not too bad.
But the early ones there all apparently had more years of PhDs in the
room than then you could be alive for one lifetime, you know, and
the stories were always really know the characters and the stories were really hilarious.
So yeah, future Ama, go watch it. They won't be disappointed.
That's the one that's always been on my list, but I never quite get
around you haven't watched it. Okay, I've watched it with my kids a
couple of times, and it's a huge hit. Some of them you have
to be like, maybe we should watch this anymore. Yeah, some of
it looks like some of the humor might be a little bit off color.
Yeah, it looks pretty There's one episode where they actually published a mathematics paper
because they solved the mathematics problem. It was like a professor fans were invented
like a brain switch, like a head switching machine, but the point was,
once you'd switched with one person, you couldn't switch back, and they
actually had to invent a new mathematical theory to show that it was possible to
switch back, and they published it as part of the show. I think,
yeah, it's really funny, very cool. All right, well thanks
for coming Samuel. This was a ton of fun, such interesting stuff,
fantas. It was a pleasure to be here and to ask me a questions.
Yeah, all right, Well we'll wrap it up here until next time. Max out