WEBVTT

1
00:00:00.280 --> 00:00:03.799
Hey, welcome back to the Ruby
Dev Summit. I'm so excited. I

2
00:00:03.799 --> 00:00:08.759
am here with Samuel Williams. Now
Samuel lives on the upside down part of

3
00:00:08.800 --> 00:00:12.800
the world, you know, where
it curves curves under. Uh he's he's

4
00:00:12.800 --> 00:00:18.679
from New Zealand and he he's working
on some really really interesting projects. Maybe

5
00:00:18.679 --> 00:00:22.120
I'll let him tell about it a
little bit more, but the projects are

6
00:00:22.960 --> 00:00:27.719
a sink and Falcon. And Falcon
in particular is interesting because it's like an

7
00:00:28.120 --> 00:00:31.320
HTTP server or something that it's like, oh, you're writ in that and

8
00:00:31.359 --> 00:00:37.920
Ruby. That's that's wild. Reminds
me of Mongrel with what's his name z

9
00:00:38.119 --> 00:00:44.119
right Mongrel anyway, So uh yeah, excited to talk about it. And

10
00:00:44.679 --> 00:00:47.719
I think we're going to get a
different perspective here because I've either been talking

11
00:00:47.719 --> 00:00:53.119
to people who build Ruby engines,
right like Opal or you know, I'm

12
00:00:53.159 --> 00:00:56.039
trying to get Truffle Ruby or somebody
on. But you know, people who

13
00:00:56.119 --> 00:00:59.560
work on c Ruby. And then
you know, I had Amir Rajon who

14
00:00:59.640 --> 00:01:02.679
works on Dragon Ruby, which is
a Ruby engine but it's built for video

15
00:01:02.719 --> 00:01:07.000
games, which that was a fun
talk, you know. And then I've

16
00:01:07.000 --> 00:01:10.879
got people who work out there in
the ecosystem building open source. But you

17
00:01:10.879 --> 00:01:15.879
know, again it's mostly web like
web development, so you know web frameworks

18
00:01:15.159 --> 00:01:19.439
are working in Rails, and so
yeah, the perspective here is different.

19
00:01:19.439 --> 00:01:23.079
I'm gonna stop talking and let Samuel
talk. Samuel welcome. I'm just gonna

20
00:01:23.079 --> 00:01:26.120
throw the question at you and you
can kind of take it from here.

21
00:01:26.400 --> 00:01:30.840
But what is what is the future
of Ruby? Gosh, that is a

22
00:01:30.879 --> 00:01:40.079
really good question. I think that
for me, Ruby is a great environment

23
00:01:40.599 --> 00:01:48.280
for expressing yourself as a programmer.
Uh huh. A lot of programming languages

24
00:01:49.079 --> 00:01:56.200
I feel get bogged down in the
detail of the language, and I always

25
00:01:56.200 --> 00:02:02.280
felt like with Ruby didn't take There
wasn't too much like ped entry in the

26
00:02:02.319 --> 00:02:07.040
code. Like it was it was
straightforward to write the programs that I wanted

27
00:02:07.040 --> 00:02:14.639
to create. Many years ago,
I was working on a property management application

28
00:02:14.800 --> 00:02:21.240
written objective C and I started hacking
on a web version of this and I

29
00:02:21.240 --> 00:02:24.879
started using Rails, and I felt
like it was a really great platform,

30
00:02:27.639 --> 00:02:37.400
but it was kind of there were
some pieces missing for me. HM.

31
00:02:38.879 --> 00:02:43.000
When I was working on that particular
problem, I was interested in scalability and

32
00:02:43.000 --> 00:02:46.680
how you build applications that can handle
as of requests. And one area where

33
00:02:46.719 --> 00:02:53.719
I came about this problem was actually
a DNS server. And so in my

34
00:02:53.800 --> 00:02:59.840
home network, I wanted to make
a custom DNS server to back in the

35
00:03:00.039 --> 00:03:04.639
had old days with ADSL modems,
if you wanted to host a website inside

36
00:03:04.680 --> 00:03:08.120
your network and still have the domain
name resolved, you would have to have

37
00:03:08.520 --> 00:03:15.759
a DNS server that would return the
local IPA dress inside your home network for

38
00:03:15.800 --> 00:03:20.520
the webs wow locally. And if
you were like on the Internet, you

39
00:03:20.560 --> 00:03:23.039
would have to have a DNIS server
that would return your ADSL modems ipadriss so

40
00:03:23.039 --> 00:03:28.599
you could do port fording like poor
ad or whatever, right, And so

41
00:03:28.800 --> 00:03:30.639
I was trying to build this website, like, well, this is kind

42
00:03:30.639 --> 00:03:34.000
of an interesting problem, and so
I kind of switchedcars a little bit,

43
00:03:34.240 --> 00:03:38.000
and I wanted to build a DNS
server that could do this for me.

44
00:03:38.319 --> 00:03:40.919
And I thought this, you know, Ruby seems like a reasonable language.

45
00:03:40.919 --> 00:03:45.080
Is it's basically just pan matching on
the host name and then returning a different

46
00:03:45.159 --> 00:03:50.479
DNS How hard could it be?
And so I created a probably one of

47
00:03:50.560 --> 00:03:54.800
my first gyms. It was called
Ruby DNS and it was a a DNIS

48
00:03:54.840 --> 00:04:00.360
server for Ruby. And the first
time I ran this my whole network like

49
00:04:00.439 --> 00:04:06.599
crash. Yeah, running single three
to DNS service isn't you know, very

50
00:04:06.639 --> 00:04:13.080
practical. Essentially, every computer in
your network is doing DNS queries like multiple

51
00:04:13.120 --> 00:04:21.480
queries second, and if your DNS
server can't handle the incoming load will stop

52
00:04:21.519 --> 00:04:26.000
working, like your web browser will
stop working time, you know, into

53
00:04:26.319 --> 00:04:30.800
stop everything, just like cries to
a whole So I started, you know,

54
00:04:30.800 --> 00:04:35.920
it was my first real experience of
concurrency and scalability problems because it's just

55
00:04:35.959 --> 00:04:38.839
like, well, this is an
easy problem, like, you know,

56
00:04:38.839 --> 00:04:41.959
it's a well defined problem. You
know, message comes in, do some

57
00:04:42.000 --> 00:04:46.759
kind of computation, you respond,
you know, it's really straightforward. And

58
00:04:46.839 --> 00:04:53.600
I felt like really didn't provide the
right tools to solve it, and that

59
00:04:53.600 --> 00:04:57.519
that to me was a little disappointing
because it's like, well, the code

60
00:04:57.560 --> 00:05:00.360
itself is clear. You know,
I can write down what I want,

61
00:05:00.399 --> 00:05:01.959
which is I want to pay and
match this host name and return this IP

62
00:05:02.079 --> 00:05:08.199
address if ther comes from inside the
network. Otherwise like pass the request down

63
00:05:08.319 --> 00:05:14.519
you know, to the to the
I s p's so so so to me,

64
00:05:14.600 --> 00:05:18.600
like it was a straightforward problem.
But the way that Ruby, the

65
00:05:18.639 --> 00:05:27.480
tools that Ruby provided to solve that
problem, weren't weren't necessarily convenient or scalable,

66
00:05:27.839 --> 00:05:30.879
or it wasn't even maybe obvious even
if Ruby at the time could do

67
00:05:31.000 --> 00:05:35.120
that, like how you would go
about doing it. So in that first

68
00:05:35.160 --> 00:05:41.600
instance, I started trying to work
on the multi thread of DNIS server,

69
00:05:42.040 --> 00:05:48.000
and that was difficult because it's still
has scalability issues. And I started learning

70
00:05:48.000 --> 00:05:55.839
about like new texts and and parallelism
and all these like sort of challenges associated

71
00:05:55.839 --> 00:06:02.000
with using threads, and that those
challenges they weren't insurmountable. But I felt

72
00:06:02.000 --> 00:06:06.800
like, now my code is much
less clear. I'm writing this code,

73
00:06:06.800 --> 00:06:12.279
I have to deal with these concerns
around concurrency that in PARALYSM they didn't really

74
00:06:12.279 --> 00:06:15.759
want to. I just want to
say, basically like here's a request block

75
00:06:15.800 --> 00:06:17.079
of code that handles the request,
and here's the response, and then we'll

76
00:06:17.199 --> 00:06:21.639
deal with anything else. So at
this time specifically, I started working on

77
00:06:21.680 --> 00:06:27.759
an interesting test case for this,
which was called Wikipedia DNS, which is

78
00:06:27.800 --> 00:06:34.279
a DNS server which it basically doesn't
HGP request to Wikipedia to get the summary

79
00:06:34.319 --> 00:06:41.040
for a topic, and so you
can get Wikipedia summaries through DNS, and

80
00:06:41.160 --> 00:06:45.439
so what was interesting that this problem
was that I had to do an HTPP

81
00:06:45.560 --> 00:06:49.800
request and so as you can imagine, doing hp request is kind of slow,

82
00:06:50.759 --> 00:06:54.720
and so it was an interesting test
case for me because I was like,

83
00:06:54.720 --> 00:06:59.279
how do you make a DNS server
that's doing this more efficient and scale

84
00:06:59.319 --> 00:07:03.079
better? This problem is the same
problem as you see applications and in other

85
00:07:03.360 --> 00:07:13.639
types of response systems. And so
at that time, Tony Tony rc Area,

86
00:07:13.639 --> 00:07:16.879
I think it's how he pronounce his
last name. He was working on

87
00:07:17.079 --> 00:07:24.319
celluloid and he was working on actor
based concurrency. So active based concurrencies where

88
00:07:24.399 --> 00:07:32.839
you define essentially a unit of work
and that unit of work happens independently of

89
00:07:32.879 --> 00:07:36.680
other units of work, and it
uses the actor model, which is message

90
00:07:36.680 --> 00:07:41.439
passing. So you have these different
light systems. You have like a every

91
00:07:41.439 --> 00:07:44.560
connection that comes in could be its
own actor, and then when it needs

92
00:07:44.600 --> 00:07:46.839
to do an HTV request, goes
and talks to another actor, and the

93
00:07:46.920 --> 00:07:50.120
actor itself is then responsible for doing
the ht requests, and once that request

94
00:07:50.199 --> 00:07:53.079
is furnished, it comes back to
the original beas is, Hey, you

95
00:07:53.120 --> 00:07:56.959
can keep on going. Yeah,
And then a lot of those systems,

96
00:07:56.959 --> 00:08:03.720
those actors are separate processes. They
can be or separate threads, and so

97
00:08:03.279 --> 00:08:05.439
at that time I was like,
well, this is seems like a neat

98
00:08:05.560 --> 00:08:09.439
idea, Like maybe this is the
right approach, And so I started working

99
00:08:09.480 --> 00:08:13.279
down, you know, going down
that pathway and building that and so I

100
00:08:13.279 --> 00:08:16.439
built celluloid. Danis and I worked
on the cellulord gym quite a bit.

101
00:08:18.439 --> 00:08:26.120
But the biggest disappointment there, I
think was the fact that celluloid was so

102
00:08:26.279 --> 00:08:35.360
complex that it kind of collapsed under
its own Weightman complexity was just to agree.

103
00:08:35.639 --> 00:08:37.759
And I think the actor model,
when you start trying to build a

104
00:08:37.759 --> 00:08:45.720
practical actor model, does get extremely
complex, like supervisors linking actors together.

105
00:08:46.399 --> 00:08:50.279
One particular piece of code that really
bothered me was this concept of linking actors

106
00:08:50.279 --> 00:08:54.759
together. And so the linked actors, where one actor crashes, the other

107
00:08:54.759 --> 00:08:58.600
will get informed of late restarts.
Kind of forms a supervisor relationship. So

108
00:08:58.240 --> 00:09:03.200
if you have like say a web
server, and that web server blows up,

109
00:09:03.399 --> 00:09:07.000
you have another actor whose sole purpose
it is to restart that server for

110
00:09:07.039 --> 00:09:09.200
example. Right, this is this
is how a lot of the ear laying

111
00:09:09.320 --> 00:09:13.840
and elixir stuff works. That's correct, Yeah, yeah, And I'm not

112
00:09:13.879 --> 00:09:16.200
really like criticizing earl and elixir I
think they're great systems for the problems they

113
00:09:16.320 --> 00:09:20.919
solved. But for me personally in
Ruby with Sally Lloyd, the piece of

114
00:09:20.919 --> 00:09:24.000
code that bothered me the most was
this one piece of code which basically has

115
00:09:24.039 --> 00:09:28.679
like a five second time out where
it basically tries to talk to another actor

116
00:09:28.679 --> 00:09:33.000
and if it doesn't respond in five
seconds, it just blows up basically,

117
00:09:33.159 --> 00:09:37.759
And I was just like, why
is it five seconds? Like and the

118
00:09:37.840 --> 00:09:43.480
whole, the whole like semantic building
like building block above. It was all

119
00:09:43.519 --> 00:09:48.279
based on this kind of like implementation
detail that really bothered me, and it

120
00:09:50.440 --> 00:09:56.919
the challenge there is there were too
many choices to be made and the semantic

121
00:09:56.919 --> 00:10:01.240
complexity just got out of control.
And so as a consequence, Sally Lloyd

122
00:10:01.320 --> 00:10:03.039
never really reached a one point over
release. There was never a point where

123
00:10:03.039 --> 00:10:07.159
we could say, hey, this
is what Sallyloyd is and and this is

124
00:10:07.159 --> 00:10:11.120
the foundation of what you can build
other things. So I basically built like

125
00:10:11.159 --> 00:10:15.000
a version of Ruby DNIS that worked
on Stellulod. All the way to the

126
00:10:15.039 --> 00:10:16.799
end point I was just like this
is I just can't I don't want to

127
00:10:16.799 --> 00:10:24.759
release this, and so at that
point I made the decision to release to

128
00:10:24.840 --> 00:10:26.600
work on, like to do this
myself. I kind of got sick of

129
00:10:26.600 --> 00:10:30.840
depending on other people's ideas, was
like, and I kind of know what

130
00:10:30.879 --> 00:10:33.200
I want to do this right.
And that was the birth of ASIN,

131
00:10:33.480 --> 00:10:41.960
the gym that I created for doing
Ruby's concurrency concurrency within Rubius, and so

132
00:10:43.279 --> 00:10:46.120
asink was was born out of frustration. I suppose you could call it frustration

133
00:10:46.240 --> 00:10:52.799
development. That's frustration development. You
know, there are a lot of very

134
00:10:52.840 --> 00:11:00.000
great things that came out of frustration
driven development. Absolutely, and I knew

135
00:11:00.240 --> 00:11:03.480
like for me, like one of
the key goals was having a specific,

136
00:11:03.840 --> 00:11:09.320
a well specified interface and having that
well specified interface as quickly as possible,

137
00:11:09.960 --> 00:11:16.960
and and and not not trying to
and not let the scope of the problem

138
00:11:16.000 --> 00:11:20.360
and Samandis create beyond what was manageable, because ultimately, when you start doing

139
00:11:20.440 --> 00:11:24.720
that, it's the it's actually the
engineers who pay the price of complexity.

140
00:11:24.279 --> 00:11:28.320
As a as a person who is
trying to solve and build a foundation for

141
00:11:28.480 --> 00:11:37.960
the engineers, every decision you make
is at least I personally think, if

142
00:11:37.960 --> 00:11:43.120
this is not complexity, I can
solve and hide from the user. Am

143
00:11:43.159 --> 00:11:48.360
I am I comfortable with exposing that
complexity to the interface that the engine is

144
00:11:48.440 --> 00:11:52.000
ultimately you have to build the applications
on, because when you start doing that,

145
00:11:52.360 --> 00:11:56.159
then instead of you paying the price, you're basically just passing it on

146
00:11:56.399 --> 00:11:58.720
and saying, hey, I can't
solve this problem. Yere you deal with

147
00:11:58.759 --> 00:12:01.399
it and then what you deal with
Instead of you solving that complexity in one

148
00:12:01.440 --> 00:12:07.159
place, you're basically forcing every engineer
who interacts with your interface to solve their

149
00:12:07.200 --> 00:12:11.960
complexity. And they spoke buggy an
incomplete way, right, So I think

150
00:12:13.080 --> 00:12:13.960
it was really important to me to
say, hey, look, this is

151
00:12:15.000 --> 00:12:18.879
the interface I'm going to have,
you know, and for me, there

152
00:12:18.960 --> 00:12:22.679
was a task based interface where tasks
run concurrently, a well defined way of

153
00:12:22.720 --> 00:12:26.919
starting them, a well defined life
cycle, and essentially being able to say,

154
00:12:26.960 --> 00:12:31.639
hey, this is this is the
whole interface. The implementation will probably

155
00:12:31.639 --> 00:12:35.120
get better, but this is the
interface. This is the fundamental foundation which

156
00:12:35.639 --> 00:12:39.080
I think concurrency should work. And
so there was a stable flag built that

157
00:12:39.159 --> 00:12:41.360
and released it I think in like
three months, Like I can't miss you

158
00:12:41.360 --> 00:12:43.440
remember the exec details, but I
think we got to a one point of

159
00:12:43.440 --> 00:12:48.879
release of facing pretty quick and that
was that's you know, that was you

160
00:12:48.879 --> 00:12:56.240
know, the rest is history I
suppose so, so yeah, So the

161
00:12:56.320 --> 00:12:58.720
question was what is the future Ruby? Do you think concurrency is the future

162
00:12:58.759 --> 00:13:07.559
Ruby? Then this kind of concurrency. So look, I suppose my mental

163
00:13:07.600 --> 00:13:16.000
model has always been Ruby is is
a language and instead of tooling and frameworks

164
00:13:16.000 --> 00:13:20.159
that as well utilized across the work
ecosystem, like lots there's lots of big

165
00:13:20.200 --> 00:13:28.159
companies using Ruby, right. And
one of the things I've talked about often

166
00:13:28.159 --> 00:13:31.519
in my in my presentations in conference
talks is I try and give like a

167
00:13:31.559 --> 00:13:37.360
few minutes on climate change and talk
about the nature of it and technology and

168
00:13:37.360 --> 00:13:41.759
how we're I don't plan to be
an expert on this topic, but like

169
00:13:41.919 --> 00:13:46.600
being a parent, is kind of
concerning like what's happening right now. And

170
00:13:46.120 --> 00:13:50.120
I think technology, I think that
I have to say I'm probably like a

171
00:13:50.159 --> 00:13:56.240
technologist in terms of like what solutions
we're looking towards. I think it's just

172
00:13:56.240 --> 00:14:01.919
because that's who I am, right, and it's Ruby as being a technology

173
00:14:01.960 --> 00:14:07.279
which is widely adopted, but that
the models and technologies that we use with

174
00:14:07.399 --> 00:14:11.279
then Ruby to achieve scalability are less
efficient than they than they could be.

175
00:14:11.799 --> 00:14:20.600
Ok. And so I think that
my goal has always been to provide more

176
00:14:20.639 --> 00:14:28.120
efficient primitives to build web applications with
Ruby, and in particular to retrofit existing

177
00:14:28.120 --> 00:14:35.759
applications with minimal changes to take advantage
of that increase concurrency and scalability. So

178
00:14:35.879 --> 00:14:39.240
give you like a really practical example
of this. We had one of my

179
00:14:39.320 --> 00:14:43.480
friends had an application that was running
on like, I don't know, up

180
00:14:43.480 --> 00:14:46.720
to eight instances of Perma and it
still had like ladies issues when there was

181
00:14:46.759 --> 00:14:50.600
a spike and load and it wasn't
it was mostly ir that they were doing.

182
00:14:52.000 --> 00:14:54.720
And they migrated to Falcon and they
got it down to like one instance

183
00:14:54.759 --> 00:14:58.480
and I think one more instance for
worse or something like that. Oh wow,

184
00:14:58.120 --> 00:15:01.039
So like this the kind of like
success story in a way, I

185
00:15:01.039 --> 00:15:07.320
suppose, because for me, you
know, someone could take an existing application

186
00:15:07.399 --> 00:15:13.480
with minimal changes, run on Falcon
and then reduce their carbon footprint of the

187
00:15:13.480 --> 00:15:18.279
application. I suppose you could call
it so like the future of Ruby in

188
00:15:18.279 --> 00:15:22.360
my mind, Like for me personally, you know, apart from all the

189
00:15:22.360 --> 00:15:26.000
great work that people are doing,
because there's a lot of it is more

190
00:15:26.039 --> 00:15:31.399
about how do we take all that. That's what I'm looking for velocity.

191
00:15:31.559 --> 00:15:37.000
You know, all of this lines
of source code and make them more efficient

192
00:15:37.399 --> 00:15:41.240
and work efficient. And so I
think for me, the future of Ruby

193
00:15:41.480 --> 00:15:50.039
is all about efficiency and doing more
with less and that's pretty much what underpins

194
00:15:50.440 --> 00:15:56.360
the async model. You know,
we can do more IO with less CPU

195
00:15:56.600 --> 00:16:03.759
cause basically, well it's it's funny
too because you know you're talking about this

196
00:16:03.840 --> 00:16:07.480
in terms of like climate change,
and you know how well we're using the

197
00:16:07.519 --> 00:16:11.159
resources we have. But the reality
is is that it's actually if you can

198
00:16:11.240 --> 00:16:15.480
run it on less cores, maybe
with less memory, it's cheaper anyway,

199
00:16:15.559 --> 00:16:18.080
right, It's a way saves money. Yeah, absolutely, Like then,

200
00:16:18.159 --> 00:16:21.799
since I gave before the example I
gave before, it was saving money.

201
00:16:21.960 --> 00:16:29.960
So yeah, I think that there
is Look, everyone has their own use

202
00:16:30.000 --> 00:16:33.399
cases and in their applications. Sometimes
the CPU be sometimes that I hev.

203
00:16:33.440 --> 00:16:41.840
It really depends, But I wouldn't
want to say my experience with real replications

204
00:16:41.840 --> 00:16:47.000
across large companies as extensive. I've
worked with a handful of them, and

205
00:16:47.039 --> 00:16:49.440
I get to see people with the
internals of people's applications and look at tracing

206
00:16:49.519 --> 00:16:53.879
and and APMs and whatnot, and
they looked at the data. There's only

207
00:16:53.879 --> 00:17:00.159
so much you can achieve in one
lifetime. But from my experience, a

208
00:17:00.159 --> 00:17:07.559
lot of applications are iobou they are. You know, anytime you have a

209
00:17:07.599 --> 00:17:11.319
web request, you know the h
GDP or something like that, you potentially

210
00:17:11.319 --> 00:17:17.759
significantly I abound. And I suppose
there's lots of strategies to deal with that.

211
00:17:18.720 --> 00:17:25.039
Sometimes people use background jobs, sometimes
they will use background threads. There's

212
00:17:25.079 --> 00:17:33.079
all sorts of strategies you can use
to deal with improving the efficiency and performance

213
00:17:33.160 --> 00:17:34.880
of this type of code. But
I think, like a lot of it,

214
00:17:36.079 --> 00:17:41.319
a lot of the time you have
the trade off of code complexity versus

215
00:17:41.359 --> 00:17:49.640
efficiency. And there was a talk
that really inspired me initially, h I

216
00:17:49.640 --> 00:17:52.799
don't the talk really inspired me.
I think the conclusion of the talk,

217
00:17:53.319 --> 00:17:56.559
like many years later, was ultimately
not as good as I hoped it would

218
00:17:56.599 --> 00:18:03.920
be. But there's a talk C
plus plus courroutines and negative overhead abstraction which

219
00:18:03.039 --> 00:18:08.680
really inspired me when I was looking
at curroutines and fibers. This talk basically

220
00:18:08.680 --> 00:18:12.880
starts right from the beginning and looks
at how traditional punch card computers work and

221
00:18:12.920 --> 00:18:17.680
how you have like a stack of
punch cards and you basically step by stick

222
00:18:17.880 --> 00:18:19.799
to build like a compiler. You
take your punch cards, and they go

223
00:18:19.799 --> 00:18:22.880
from one machine to the next,
and they go to the next machine,

224
00:18:22.880 --> 00:18:26.319
and you're taking these whole stacks of
cards. And they were basically saying,

225
00:18:26.359 --> 00:18:30.920
well, how do we like that
If every step takes ten seconds, then

226
00:18:30.960 --> 00:18:36.480
the total processing time there's going to
be like ten seconds times a number of

227
00:18:36.519 --> 00:18:40.920
steps. So how do we make
this faster? And their their solution was

228
00:18:40.960 --> 00:18:42.839
to when one punch card is finished
from one machine, you put it to

229
00:18:42.880 --> 00:18:47.880
the next machine. Basically, so
instead of every step taking ten seconds,

230
00:18:47.880 --> 00:18:51.400
you can kind of combine them all
together because the punch card is flowing to

231
00:18:51.559 --> 00:18:57.519
end. And but traditional programs don't
work there, like a function call.

232
00:18:57.799 --> 00:19:00.920
When you make a function call basically
saying hey, here is a bunch of

233
00:19:00.960 --> 00:19:06.440
inputs and then give me give me
some result hm. And there's there's no

234
00:19:06.519 --> 00:19:08.680
easy you know, if you if
you feed in ten gigabytes of data,

235
00:19:08.880 --> 00:19:11.359
it's going to churn away on that
data and then come back and say here's

236
00:19:11.359 --> 00:19:18.400
your team gigabytes or whatever. And
so this is kind of the same problem

237
00:19:18.480 --> 00:19:19.480
as the punch cards. You know, if you have a whole bunch of

238
00:19:19.519 --> 00:19:23.799
functions you want to chain together,
then the total lazy of the system is

239
00:19:23.799 --> 00:19:27.279
all the individual steps added together,
right, and you can't really avoid that.

240
00:19:29.079 --> 00:19:32.640
So the whole idea of a co
routine is to kind of short circuit

241
00:19:32.640 --> 00:19:37.079
there so that when one function is
finished with one data point, that can

242
00:19:37.160 --> 00:19:41.440
just pass it onto the next function. And so this instead of being like

243
00:19:41.720 --> 00:19:45.400
running and they're very manular level,
they're running kind of almost and lockstep on

244
00:19:45.440 --> 00:19:49.039
one data point at a time to
hold through the whole pipeline. So this

245
00:19:49.119 --> 00:19:53.759
talk that I watched about C plus
plus curatoons and negative overhead abstraction really inspired

246
00:19:53.799 --> 00:20:00.839
me because I never thought about negative
negative overhead abstraction. You know what I

247
00:20:00.839 --> 00:20:06.400
mean about this is when you look
at languages like jazzascript for like pulling this

248
00:20:06.440 --> 00:20:11.279
one out, but you see things
like a single waight the keywords, and

249
00:20:11.319 --> 00:20:14.759
everyone is like, wow, you
know now we can do like a single

250
00:20:14.799 --> 00:20:17.640
weight, And I'm just like,
so you have to add these keywords everywhere

251
00:20:18.119 --> 00:20:22.400
and like we write all the code
and yeah, I'm like, this is

252
00:20:22.440 --> 00:20:25.359
really problem. I want to spend
my time doing, you know, like

253
00:20:25.400 --> 00:20:29.319
I want to go through my whole
code base and rewrite everything. You know,

254
00:20:29.400 --> 00:20:33.119
imagine if if multi process or multiple
threads were like that kind of cooperative

255
00:20:33.119 --> 00:20:37.960
concurrency with explicit keywords for yielding.
At every point that you thought yielding would

256
00:20:37.960 --> 00:20:41.240
makes sense, it would be another
year. And you see this in the

257
00:20:41.359 --> 00:20:47.720
very practical terms. You see like
JavaScript libraries which have both synchronous and asynchronous

258
00:20:47.720 --> 00:20:52.720
interfaces for the same Yeah, and
a really common example of where I think

259
00:20:52.759 --> 00:20:56.160
this is a huge problem is logging. Now, and probably there's other ways

260
00:20:56.160 --> 00:21:00.920
of solving this at the core of
JavaScript, but if you have a log

261
00:21:00.000 --> 00:21:03.599
function and the log function is doing
some kind of ir I you always get

262
00:21:03.640 --> 00:21:07.680
to go through the entire source curtain
and change your log function from like a

263
00:21:07.720 --> 00:21:11.680
synchronous log function to an asynchronous one, just because like maybe the back end

264
00:21:11.799 --> 00:21:15.079
change from standard through like an HQP
to an APM or something. I don't

265
00:21:15.200 --> 00:21:19.160
like. It has always struck me
as odd that people would want to go

266
00:21:19.200 --> 00:21:25.279
through and retarget them and rebuilt interfaces
and make concurrency and explicit part of the

267
00:21:25.319 --> 00:21:29.480
interface when actually it's much more convenient
when it's implicit. I do give these

268
00:21:29.559 --> 00:21:32.279
arguments for both sides there, but
for me, I'm lying firmly on the

269
00:21:32.319 --> 00:21:40.480
implicit side. Right. So I
suppose with JavaScript being so explicit, has

270
00:21:40.480 --> 00:21:45.200
some advantages, but it also has
some big disadvantages. And so with with

271
00:21:45.359 --> 00:21:52.319
curroutines, I felt it's a great
model because at less you hide a lot

272
00:21:52.319 --> 00:21:57.319
of the scheduling, and so with
acing, I was like, okay,

273
00:21:57.319 --> 00:22:00.759
i' many of use fibers to do
this to try and hide the scheduling,

274
00:22:02.799 --> 00:22:10.839
and it's a kind of green thread
model. So with acink one point zero,

275
00:22:12.160 --> 00:22:15.920
I wanted to show the proof of
concept. I wanted to show I

276
00:22:15.000 --> 00:22:18.720
want to give interface correct, but
I also wanted to show like this was

277
00:22:18.799 --> 00:22:22.400
feasible, and so acin one used
a lot of rappers internally to do IO

278
00:22:22.519 --> 00:22:26.599
and make sure that I was not
blocking and it didn't necessarily pick up every

279
00:22:26.640 --> 00:22:32.000
single operation. There were a couple
of like outstanding ones like waiting on a

280
00:22:32.039 --> 00:22:38.079
process to exit or DNS resolution would
be like another one that that acink one

281
00:22:38.079 --> 00:22:48.119
pointer didn't handle concurrently. So after
I felt like ACNC like it seemed successful,

282
00:22:48.160 --> 00:22:49.799
like I could build like a web
server and I could run applications on

283
00:22:49.839 --> 00:22:53.480
and it basically just worked as I
hoped it would. So I went to

284
00:22:53.559 --> 00:23:00.640
Matt's at Ruby World conference I think
in twenty nineteen or sometimes around there,

285
00:23:00.200 --> 00:23:03.519
and I said to Matt's, Look, we've got a perfectly like I've built

286
00:23:03.519 --> 00:23:10.519
this proof of concept, like it
works. It gives you insane scalability.

287
00:23:10.559 --> 00:23:15.079
And I think I demonstrated the Ruby
comf Taiwan and a talk called the Journey

288
00:23:15.119 --> 00:23:18.519
to one Million where we did one
million simultaneous web sockets and a single Ruby

289
00:23:18.599 --> 00:23:26.119
process, which oh wow, yeah, it's a fun demo. Yeah sorry,

290
00:23:26.119 --> 00:23:30.839
go ahead, No, I'm just
saying that that's amazing. Yeah,

291
00:23:30.920 --> 00:23:33.680
Matt, Matt's pressed the button on
the keyboard to do the final connection.

292
00:23:33.759 --> 00:23:42.400
So it was great, and I
think, uh that that whole experience.

293
00:23:42.920 --> 00:23:45.920
I started looking at the performance because
you know, now we've got the proof

294
00:23:45.920 --> 00:23:52.720
of concept, we've kind of proven
the interface. What's the next step,

295
00:23:52.759 --> 00:23:56.880
So I said, to Matt's,
we need to make it possible to hook

296
00:23:56.960 --> 00:24:04.880
into Ruby's internal schedule operations so that
we can redirect those operations to the some

297
00:24:06.000 --> 00:24:11.359
kind of scheduler that can then manage
the fibers and have some kind of event.

298
00:24:11.400 --> 00:24:18.440
Look, so a schedulist job in
Ruby is to basically take an operation

299
00:24:18.519 --> 00:24:22.839
like a web request, and if
that request is going to take some time

300
00:24:22.839 --> 00:24:26.559
to completely, say one hundred milliseconds, maybe you're talking to an external API

301
00:24:26.599 --> 00:24:30.960
and it's it's slow. Then the
schedulists job is to say, hey,

302
00:24:32.960 --> 00:24:37.400
I'm going to pause the code executing
right now until the operation can continue.

303
00:24:37.839 --> 00:24:45.079
And then when the operation can continue, we will resume execution. And so

304
00:24:45.119 --> 00:24:48.440
you have all these like little chunks
like in a RAG application or a DNS

305
00:24:48.480 --> 00:24:52.720
server for that matter. You basically
have like a request coming, you're going

306
00:24:52.799 --> 00:24:55.559
to do some like IR operations,
and you're going to run and you have

307
00:24:55.559 --> 00:25:00.640
a whole bunch of these operating all
concurrently. So the schedulest job is to

308
00:25:00.640 --> 00:25:03.920
basically say, well, I'm doing
this request and I can't go any further

309
00:25:04.000 --> 00:25:07.200
right now, so I'll go and
do one at some other requests. I

310
00:25:07.240 --> 00:25:10.000
can't go anyether, and I'm going
to do some other requests. Now their

311
00:25:10.119 --> 00:25:11.680
responses come back from their website,
so I can keep on going, like

312
00:25:11.720 --> 00:25:15.680
Wikipedia DNIS for example, where it
was doing an API called a Wikipedia to

313
00:25:15.680 --> 00:25:18.480
get the summary. So now I've
got the summary, I can and procese

314
00:25:18.480 --> 00:25:22.079
it and see the response. So
the schedulest job is to do all that

315
00:25:22.200 --> 00:25:26.480
work. And so what we do
is you talk about this and this sounds

316
00:25:26.559 --> 00:25:32.519
like how my friends who switched from
Ruby to no JS explained why no JS

317
00:25:32.599 --> 00:25:37.240
was better. Well, we have
it all in Ruby now, so yeah,

318
00:25:37.240 --> 00:25:38.559
we have it all in Ruby.
I tried to explain that to people.

319
00:25:38.559 --> 00:25:44.839
But anyway, so I think one
point I was the proof of concept.

320
00:25:45.079 --> 00:25:45.680
I talked to me and I said, look, MAT's we need the

321
00:25:45.680 --> 00:25:49.640
hooks and Ruby so that we can
redo it these operations to a scheduler and

322
00:25:49.680 --> 00:25:52.960
efficiently scheduled that. And so that's
what we did. And it took a

323
00:25:53.920 --> 00:25:56.599
took a couple of releases of Ruby
to kind of iron out all the tanks.

324
00:25:59.160 --> 00:26:02.759
So we had pretty normal. Yeah, it's normal. In fact,

325
00:26:02.799 --> 00:26:10.119
it's I wrote a book a blog
post that two years ago, like for

326
00:26:10.200 --> 00:26:12.680
the release of Ruby three point one
or something. I never I never published

327
00:26:12.720 --> 00:26:15.319
the blog post because as I was
writing the blog post, I found a

328
00:26:15.319 --> 00:26:19.119
bug. It was like, oh, no, I have to wait a

329
00:26:19.119 --> 00:26:25.319
whole year to like fix this bag
before I can like never came back to

330
00:26:25.359 --> 00:26:30.240
it. But so we implement the
scheduler hooks. So Ruby now has something

331
00:26:30.240 --> 00:26:34.319
called the fiber scheduler, and the
fiber scheduler is providing a whole bunch of

332
00:26:34.400 --> 00:26:38.680
hooks, a couple of like io
weight for dealing with like reads and rights

333
00:26:38.720 --> 00:26:45.680
that are blocking. Address resolve,
which deals with danais so I concurrent danis

334
00:26:45.680 --> 00:26:52.200
resolution process weight, which deals of
waiting on a child process to Except there

335
00:26:52.200 --> 00:26:55.599
are a bunch of specific ones like
io read and io right, and I'll

336
00:26:55.599 --> 00:26:57.960
talk a little bit about them in
the moment. And so there's all these

337
00:26:59.000 --> 00:27:03.680
hooks, and so the Ruby interpreter, when it's running code that the user

338
00:27:03.720 --> 00:27:07.920
wrote, if that code executes an
operation that would block it gets redirected to

339
00:27:07.960 --> 00:27:14.799
the fiber schedule, and the fiber
scheduler will then manage the concurrency of of

340
00:27:15.000 --> 00:27:21.519
multiple tasks so they can be executed
most efficiently. The benchmark I have for

341
00:27:21.599 --> 00:27:25.799
that is actually like going into this
whole problem even with Ruby DNS, was

342
00:27:25.839 --> 00:27:30.319
like, how do we run the
most lines of Ruby code as efficiently as

343
00:27:30.359 --> 00:27:37.839
possible? Is the fiber schedule is
conduct switching between between fibers and tasks and

344
00:27:38.119 --> 00:27:41.200
basically trying to execute lines as quickly
as possible. I suppose you can look

345
00:27:41.240 --> 00:27:48.440
at it that way. So I
think two point zero was the first release

346
00:27:48.480 --> 00:27:57.039
of ACNC that took advantage full advantage
of the fiber scheduler, and it was

347
00:27:57.200 --> 00:28:02.200
really like a major milestone. I
suppose Ruby, even if it's not publicly

348
00:28:02.440 --> 00:28:07.279
obvious, why you can take an
existing roomy program run it on top of

349
00:28:07.359 --> 00:28:11.720
acinc and gain significant advantages to I
concurrency and like pinch, like other forms

350
00:28:11.720 --> 00:28:18.440
of concurrency like DNIS resolution, waiting
on child process and whatnot. And so

351
00:28:19.880 --> 00:28:22.319
it's all well and good heaving this
foundation, I suppose, But maybe that

352
00:28:22.440 --> 00:28:26.480
leads us to the big topic like
Falcon and how that works and why that's

353
00:28:26.519 --> 00:28:34.359
important. So as we know,
like Ruby, it's a great environment for

354
00:28:34.400 --> 00:28:40.039
an age applications for for lots of
reasons, Rails probably being like the biggest

355
00:28:40.039 --> 00:28:48.039
one. Yeah, I felt like
my Denis server wasn't was was one like

356
00:28:48.119 --> 00:28:49.319
for me it was my proof of
concept. But then I was like,

357
00:28:49.400 --> 00:28:56.200
well surely we can write a web
server, like can it be famous?

358
00:28:56.920 --> 00:29:00.799
Right? Yeah, exactly totally.
So basically I built Falcon as a proof

359
00:29:00.839 --> 00:29:03.920
of concept to see, like,
you know how good it is it you

360
00:29:03.960 --> 00:29:07.960
know what kind of performance can we
get? And so Falcon was was born

361
00:29:08.000 --> 00:29:15.200
out of that kind of curiosity,
I suppose. Obviously we wanted to use

362
00:29:15.319 --> 00:29:22.480
rag Rack is the standard interface for
between web servers and replications in the Ruby

363
00:29:22.480 --> 00:29:26.279
world. Yeah, and if you
optimize for RACK, you optimize not just

364
00:29:26.319 --> 00:29:32.519
for rails but for Sinatra and Rhoda
and all the others because it is that

365
00:29:32.799 --> 00:29:38.200
core piece the HTTP interface to Ruby. That's right. Yeah, And so

366
00:29:41.279 --> 00:29:45.960
it's like a volcane of worms,
like oh, rack two point zero.

367
00:29:45.960 --> 00:29:48.440
When I when I started building building
Falcon, I was like, I want

368
00:29:48.440 --> 00:29:52.559
to how RACK works. And I've
done I built my own framework for Reck

369
00:29:52.599 --> 00:29:56.680
in the past, but it was
really just like, as a consumer of

370
00:29:56.720 --> 00:29:59.400
the interface, I wasn't really considering
what it's like to be on the other

371
00:29:59.440 --> 00:30:08.039
side of right equation, on the
service side. So when I went to

372
00:30:08.079 --> 00:30:14.279
the RACK issue tracker, like it
was many years ago now, there were

373
00:30:14.319 --> 00:30:17.160
like hundreds of open issues. No
one was really maintaining RACK, and I

374
00:30:17.200 --> 00:30:18.559
was like, wow, this is
a little said, this really critical piece

375
00:30:18.559 --> 00:30:22.039
of infrastructure. It's kind of I
suppose it's a little hidden from view because

376
00:30:22.519 --> 00:30:26.480
most people wouldn't really need to know
why RE exists or why it's important.

377
00:30:26.519 --> 00:30:33.519
But right, so RACK is essentially
a CGI gateway between It's basically using the

378
00:30:33.559 --> 00:30:41.720
CGI specification as an interface applications,
and so every web server that talks to

379
00:30:41.759 --> 00:30:45.039
a RACK application with a request and
then gets a response from their application.

380
00:30:45.400 --> 00:30:53.200
Is essentially using the guts of of
the CGI specification, like so as path

381
00:30:53.279 --> 00:30:59.960
info is one of the more common
like CGI fields, and it's it's defined

382
00:31:00.079 --> 00:31:07.519
either c g I or it's used
by RANK. So I was really interested.

383
00:31:07.680 --> 00:31:11.160
I was really interested in HB two
at the time. It's like,

384
00:31:11.400 --> 00:31:15.960
there weren't many good implementations of HP
two for Ruby, and so I went

385
00:31:15.000 --> 00:31:19.319
and created one. There's a gym
called an h pop does h P one,

386
00:31:19.440 --> 00:31:25.839
HP two and hopefully H three,
and and I thought, well,

387
00:31:25.920 --> 00:31:30.720
why can't we support HP two directly
from web service? It's pretty it's a

388
00:31:30.720 --> 00:31:33.680
pretty good protocol in lots of regards, like it's a bit of a HP

389
00:31:33.759 --> 00:31:38.920
one is text based, line based. H B two is using binary framing,

390
00:31:40.200 --> 00:31:44.000
and so it's it's harder to stuff
up HUP two, so it's a

391
00:31:44.039 --> 00:31:47.599
bit more secure, and it has
other advantages as well. So it's like,

392
00:31:47.759 --> 00:31:49.240
what, you know, why can't
I run a RAC application HB two.

393
00:31:49.359 --> 00:31:56.119
Well, as it turns out there's
e g I specification that that RACK

394
00:31:56.279 --> 00:32:04.200
was sort of implementing. Well,
semantically, you can always write proxies between

395
00:32:04.279 --> 00:32:07.839
HP one HB two and HP.
They've tried to have the same semandix between

396
00:32:07.880 --> 00:32:12.400
all the different versions. It's just
the protocol itself on the why that differs.

397
00:32:12.400 --> 00:32:19.400
But but Rack itself didn't really expose
a good model for that, in

398
00:32:19.400 --> 00:32:22.240
my opinion, and so I started
working on that problem. And so one

399
00:32:22.240 --> 00:32:28.880
of the biggest most important changes that
I feel like I made to Rank was

400
00:32:28.920 --> 00:32:34.559
the ability to stream requests and responses. So this means that there was a

401
00:32:35.240 --> 00:32:37.640
I had a conversation with the engineer
many years ago and they were like,

402
00:32:37.720 --> 00:32:43.000
we're generating CSV, like a lot
of CSV from a RAILS air and it

403
00:32:43.039 --> 00:32:45.119
gets buffered the whole lot, and
it's like multi ugabytes, and we're killing

404
00:32:45.160 --> 00:32:50.839
servers because because they came the whole
response. How do we start streaming this?

405
00:32:51.119 --> 00:32:54.119
And it's interesting that that's even a
complicated question to answer, in my

406
00:32:54.160 --> 00:33:00.440
opinion, because I don't think it
should be. And so Falcon and Rack

407
00:33:00.680 --> 00:33:02.720
the changes that I made, I
was sort of trying to change to make

408
00:33:02.759 --> 00:33:07.559
it easier to stream responses. And
another piece of this is like web citeits

409
00:33:08.680 --> 00:33:15.920
even today, rails still uses a
hijack mechanism, which is where it basically

410
00:33:15.920 --> 00:33:22.680
the request comes in and rails basically
steals the whole connection and plucks it in

411
00:33:22.680 --> 00:33:28.880
its own event loop, separate to
the server itself, and then starts talking

412
00:33:28.960 --> 00:33:30.880
to the website protocol on that.
But the biggest issue with that is,

413
00:33:30.920 --> 00:33:35.920
like, because it's hijacking the whole
connection, it doesn't work with HDB two,

414
00:33:35.960 --> 00:33:38.559
which supports multiplexing on a single connection, because with HB one you have

415
00:33:38.599 --> 00:33:44.839
one connection per request response, and
it's okay to take that whole connection and

416
00:33:45.519 --> 00:33:49.119
hijack that. With HB two you
have lots of individual connections running on one

417
00:33:49.160 --> 00:33:55.480
TCP connection. So I worked on
RACK and I solved this problem. We

418
00:33:55.519 --> 00:34:00.920
released RAP three three, three point
whatever. There was quite a lot of

419
00:34:00.440 --> 00:34:06.480
shown as we figured out a few
compatibility details, and so now it's possible

420
00:34:06.519 --> 00:34:10.719
to run web socits natively on a
rat compatible server that includes perma Falcon.

421
00:34:13.000 --> 00:34:15.960
I think even webrook is supported with
you know, you can just run a

422
00:34:15.960 --> 00:34:19.440
web soce straight on the request.
Yeah. Yeah. And so I was

423
00:34:19.480 --> 00:34:22.679
really pleased about this because it's sort
of kind of bait to the question,

424
00:34:22.719 --> 00:34:27.440
which what is the future of Ruby. Actually, I suppose as an engineer,

425
00:34:27.480 --> 00:34:30.920
I was really disappointed at how badly
web socits were handled in Ruby.

426
00:34:31.159 --> 00:34:36.079
It was like websites were vented?
How many years ago? And how long

427
00:34:36.119 --> 00:34:37.760
has it taken us to get to
the point where applications can just like native

428
00:34:39.880 --> 00:34:45.639
And then I think that I don't
want to be too critical, but I

429
00:34:45.639 --> 00:34:46.840
think that's how Ruby back in some
regards. You will look at that and

430
00:34:46.920 --> 00:34:50.239
go, well, Ruby can't do
this, and it's like, well,

431
00:34:50.320 --> 00:34:54.280
yeah, and how we're going to
solve that problem? And so I think

432
00:34:55.599 --> 00:35:00.679
the future of Ruby in some regards
there is catching up to do the technology

433
00:35:00.719 --> 00:35:06.880
side, but I hope that things
like Falcon and as provide the right foundation

434
00:35:07.679 --> 00:35:13.960
for building those applications and going forward
with improved concurrency and scalability. Right,

435
00:35:15.119 --> 00:35:20.920
cool, Well we've spent It's so
funny because I usually have to prompt people

436
00:35:20.960 --> 00:35:25.199
as I interview them, and you
know, to clarify more things and you

437
00:35:25.239 --> 00:35:28.639
know, and then it's like,
oh, we went for you know,

438
00:35:28.639 --> 00:35:34.000
however long and yeah, I mean
I feel like I maybe added some color

439
00:35:34.000 --> 00:35:37.159
commentary, but for the most part. It was really fascinating though, to

440
00:35:37.199 --> 00:35:39.800
have you kind of walked through that
whole process, because yeah, I mean,

441
00:35:39.840 --> 00:35:43.159
concurrency is one of the things that
I hear a lot of people talk

442
00:35:43.199 --> 00:35:47.119
about and it's some of it is
down to, yeah, am I making

443
00:35:47.159 --> 00:35:52.239
efficient use of the hardware? And
do I get the performance gains out of

444
00:35:52.079 --> 00:35:55.599
right? It has four cores?
So why am I not using four cores?

445
00:35:57.920 --> 00:36:01.360
But the other end of it is
is that and we all want that

446
00:36:01.440 --> 00:36:05.320
kind of efficiency. But but the
other side of it is is, yeah,

447
00:36:05.360 --> 00:36:09.360
you know there's some capabilities that come
along with it that that, right,

448
00:36:10.000 --> 00:36:15.119
it changes Actually it's not just about
making things more efficient. It actually

449
00:36:15.239 --> 00:36:20.960
changes applications, right, And so
just looking at that, it's it's very

450
00:36:20.960 --> 00:36:23.400
interesting to look at Okay, you
know now that I've got these things working

451
00:36:23.440 --> 00:36:29.519
for me, Yeah, I've got
I've got these options, and so that

452
00:36:29.519 --> 00:36:36.000
that's very very exciting. I'm wondering
too, because some people have left Ruby

453
00:36:36.039 --> 00:36:39.440
because of the concurrency or other concerns. Do you think we'll pull some of

454
00:36:39.480 --> 00:36:44.800
those back or do you think they're
just going to stay in whatever land they

455
00:36:44.800 --> 00:36:47.920
went to to find that? Gosh, that's a good question. Look,

456
00:36:49.239 --> 00:36:52.360
I don't presume to know what people
do or don't want as engineers. I've

457
00:36:52.400 --> 00:36:58.760
always just felt like I want to
scratch my own note. Right, Look,

458
00:36:58.760 --> 00:37:01.760
I suppose yeah, the biggest elephant
in the room. There will be

459
00:37:01.760 --> 00:37:09.199
something like Alixa and yeah, look
it's a great technology, and crystals as

460
00:37:09.239 --> 00:37:13.960
well. From my point of view, just look at as the biggest thing

461
00:37:14.039 --> 00:37:16.639
for the buck, Like if I
went to work on Crystal or Elixir and

462
00:37:16.679 --> 00:37:23.159
solve or improve their concurrency. It's
sort of like if at times like the

463
00:37:23.159 --> 00:37:27.840
size of the market or impact,
And so for me, like the size

464
00:37:27.840 --> 00:37:30.280
of the impact for Ruby is just
so much bigger, right, So it's

465
00:37:31.159 --> 00:37:35.480
even the same amount of effort because
it's multiplied by the size of the market,

466
00:37:35.760 --> 00:37:40.039
has so much more total impact,
right, And so for me personally,

467
00:37:40.039 --> 00:37:45.840
that's the equation I work from.
I'm like Ruby is a low hanging

468
00:37:45.920 --> 00:37:51.960
for it is such a great scope
for making existing applications work better and more

469
00:37:52.000 --> 00:37:58.880
efficiently. And that's what I personally
find exciting and seeing the early adopters take

470
00:37:58.960 --> 00:38:01.920
Falcon, use Falcon, you know, use acing HP and derive those in

471
00:38:01.920 --> 00:38:08.400
credible benefits and build and and and
and Finitially, that the the nature of

472
00:38:08.440 --> 00:38:13.039
the kind of application that can build
the web sockets and service and against and

473
00:38:13.039 --> 00:38:15.320
all those other kinds of technologies that
are now very easy to use. We've

474
00:38:15.360 --> 00:38:21.280
we've lowered the bar and like on
accessing that level of interactivity and so it's

475
00:38:21.280 --> 00:38:23.920
exciting to see what people do with
that. So to answer your question,

476
00:38:24.119 --> 00:38:30.119
like I suppose it doesn't really matter
because people will use the technology of the

477
00:38:30.199 --> 00:38:37.719
most comfortable with and that's okay.
Yeah, And like I suppose at least

478
00:38:37.760 --> 00:38:40.800
if someone's arguing that Ruby's not capable
of doing like concurrency, we now have

479
00:38:42.039 --> 00:38:44.559
a counterpoint, which is, hey, actually it can, and it's really

480
00:38:44.599 --> 00:38:46.719
good and it works really well.
And the only the only argument I would

481
00:38:46.719 --> 00:38:52.239
really say that that works against that
is like it's still early days, but

482
00:38:52.280 --> 00:38:54.239
like I don't expect someone like this
to be adopted overnight. Like it's already

483
00:38:54.280 --> 00:38:59.760
been six years and we've got our
early adopters, which is amazing, but

484
00:39:00.119 --> 00:39:07.320
it takes time for companies to Companies
are extremely slow on adopting new technologies,

485
00:39:07.599 --> 00:39:14.840
and so we're going to be I
said, look, I know these major

486
00:39:14.880 --> 00:39:17.920
companies using anything. I can't really
talk to them, but you know,

487
00:39:19.079 --> 00:39:22.400
it's hittening and I think that that's
a good you know, make it as

488
00:39:22.440 --> 00:39:24.880
good as we can for the engineers. If it solves an engineering problem,

489
00:39:25.239 --> 00:39:29.639
they will do like people will use
them, and I think that's yep,

490
00:39:29.719 --> 00:39:36.599
absolutely well. And it's interesting too
because as I've done these interviews and it

491
00:39:36.679 --> 00:39:38.079
kind of goes back to the point
you were making earlier, and the point

492
00:39:38.079 --> 00:39:44.000
that several others have made is that
Ruby, it is so expressive. It

493
00:39:44.079 --> 00:39:49.639
just gives you so much in the
way of how do I put it,

494
00:39:49.920 --> 00:39:52.360
So people are adopting things like Python. Python seems to be, you know,

495
00:39:52.400 --> 00:39:59.519
having a renaissance these days because it
has powerful math and science libraries that

496
00:40:00.039 --> 00:40:02.559
and it's approachable enough so that people
in academia can go and they can do

497
00:40:02.599 --> 00:40:07.039
their thing with it. Right.
So that's It's not the expressiveness of the

498
00:40:07.159 --> 00:40:12.480
language, right, It's not you
know, any of the things that in

499
00:40:12.559 --> 00:40:16.079
my opinion draw me to Ruby,
right, And so as long as it's

500
00:40:16.119 --> 00:40:22.320
fast enough, it has enough of
the right either libraries or capabilities to solve

501
00:40:22.320 --> 00:40:25.400
my problems and things like that,
right, I'm happy to use Ruby.

502
00:40:25.800 --> 00:40:30.199
And the thing that draws me in
is the way that the language is put

503
00:40:30.199 --> 00:40:35.320
together. And then if you expand
that into things like Rails or a lot

504
00:40:35.360 --> 00:40:39.280
of the other libraries, really what
you find is you find that it's those

505
00:40:39.360 --> 00:40:45.039
have adopted the same expressible approach as
Ruby. Right. So when I was

506
00:40:45.119 --> 00:40:49.599
learning rails, I learned rails and
then I learned Ruby to learn rails,

507
00:40:49.639 --> 00:40:52.320
right, and I learned Ruby through
rails. But you know, it was

508
00:40:52.360 --> 00:40:55.960
all very intuitive, and you know, kind of it got out of the

509
00:40:57.000 --> 00:41:00.719
way of me having to really deeply
know the technology, and I could really

510
00:41:00.719 --> 00:41:06.400
think about the problem space I was
in. And so yeah, to the

511
00:41:06.480 --> 00:41:08.079
extent that, hey, it gets
better and better and better and better.

512
00:41:09.199 --> 00:41:13.360
That that's the thing that excites me, right, is that it's already good

513
00:41:13.519 --> 00:41:17.559
enough. But to see some of
these advances, that that's exciting. And

514
00:41:17.840 --> 00:41:21.880
yeah, like you said, we've
got some early adopters. We've got people

515
00:41:21.920 --> 00:41:24.360
out there, you know, trying
out Falcon and acinc and things like that.

516
00:41:24.880 --> 00:41:30.159
And what I found is that these
things is they tend to make a

517
00:41:30.320 --> 00:41:35.719
difference for more and more people.
Then then the word spreads, and then

518
00:41:35.880 --> 00:41:39.039
what happens is now the state of
the art is not Puma, it's or

519
00:41:39.079 --> 00:41:43.199
maybe Puma adopts some of the things
from Falcon and it is Puma, but

520
00:41:43.280 --> 00:41:46.159
it's a Puma that's way better,
or it's Falcon, or it's Yeah.

521
00:41:46.760 --> 00:41:52.360
I have a close working relationship with
Nate and a couple of others and which

522
00:41:52.360 --> 00:41:54.599
are cross cliberate all the time.
One. Oh yeah, well I also

523
00:41:55.760 --> 00:42:00.960
because if you do something brilliant,
right and I'm using Puma, I still

524
00:42:00.960 --> 00:42:06.159
want it. Yeah, yeah,
absolutely, Well you can use acink inside

525
00:42:06.159 --> 00:42:09.960
Perma. It works fine, Yeah, you just if you have So this

526
00:42:10.079 --> 00:42:15.280
is just a fun aside. I
suppose Puma is using a thread for each

527
00:42:15.360 --> 00:42:20.000
request. There's no reason why you
can't put like a block, an ACNC

528
00:42:20.039 --> 00:42:23.360
block in their thread and then multiplex
out multiple work requests. So let's say

529
00:42:23.360 --> 00:42:27.239
you're we're working on a service as
to talk to like say, maybe you're

530
00:42:27.239 --> 00:42:31.480
doing like a you know, identity
checking system or something you need to talk

531
00:42:31.519 --> 00:42:36.920
to like three different remote systems to
validate someone's bank details, address or something

532
00:42:36.920 --> 00:42:39.159
else, and you want to talk
do that as quickly as possible, even

533
00:42:39.320 --> 00:42:43.199
inside Perma. Well, I guess
you have two options. You can use

534
00:42:45.239 --> 00:42:51.480
ah is it called ethon, There's
like a there's something called Hydra. There's

535
00:42:51.480 --> 00:42:53.519
a gem which works on top of
lib curl. I think unless you do

536
00:42:53.639 --> 00:42:59.559
like comparency multiple requests simultaneously, or
you can just drop in an ACNC block

537
00:42:59.599 --> 00:43:04.159
and just do you is XGP and
it will work as well or it's not

538
00:43:04.280 --> 00:43:09.599
probably better and so like you can't
embed as and consider perm and derived significant

539
00:43:09.639 --> 00:43:14.960
benefit if you know, if you
have explicit ioconcurrency that you want to solve

540
00:43:15.039 --> 00:43:16.960
for. So, yeah, it's
pretty neck like it's it's it is very

541
00:43:17.000 --> 00:43:25.159
composable in networkun cool. I'll check
that out too, all right, Well,

542
00:43:28.639 --> 00:43:32.840
are there any other things coming in
the Ruby or the Ruby community eco

543
00:43:32.920 --> 00:43:39.760
system core length you're jazzed about.
Yeah. One of the thingsures I've been

544
00:43:39.760 --> 00:43:46.199
working on in Ruby tangentially is io
buffer, which is an alternative to using

545
00:43:46.239 --> 00:43:52.639
strings for network io. Okay,
it's currently markets experimental, it's been in

546
00:43:52.840 --> 00:43:55.960
like the last two or three releases
of Ruby, and it's used by the

547
00:43:55.960 --> 00:44:07.800
fiber scheduler too. Have an efficient
zero copy mechanism for basically saying we have

548
00:44:08.000 --> 00:44:12.119
a string and we want to read
into a part of that string, like

549
00:44:12.159 --> 00:44:15.840
someone's trying to read data from the
network into the string. We don't want

550
00:44:15.840 --> 00:44:19.239
to like just read data and then
copy it in there. And so io

551
00:44:19.320 --> 00:44:22.400
buffer can be a slice of that
string and we can efficiently pass that into

552
00:44:22.400 --> 00:44:29.800
the Rubies fiber scheduler and then the
five responsible for reading into that piece the

553
00:44:30.159 --> 00:44:35.880
buffer. The surprisingly, I've had
bug reports from like lots of people in

554
00:44:35.920 --> 00:44:38.559
a bad way, like people trying
to do stuff and finding inconsistencies or all

555
00:44:38.679 --> 00:44:43.400
things together. And I was surprised
because I didn't think people would be using

556
00:44:43.400 --> 00:44:49.400
it as much, even as marked
as experiments. But this is one of

557
00:44:49.440 --> 00:44:52.559
my goals that things get better,
So that's fine, Yeah, exactly right.

558
00:44:52.639 --> 00:45:00.880
One of my goals is to try
and tam zero copy networking, and

559
00:45:01.000 --> 00:45:08.039
Ruby Ruby right now does because of
the way strings are designed can be each

560
00:45:08.119 --> 00:45:15.519
cases for networking, IO can be
quite complex to avoid copying data. Copying

561
00:45:15.599 --> 00:45:19.199
data isn't exactly the worst thing you
can do, but CPUs only have a

562
00:45:19.199 --> 00:45:22.840
bandwidth of like between fifteen hundred gigabytes
per second of memory bandwidth, and so

563
00:45:22.920 --> 00:45:27.840
like the less of that you consume
just copying data because you do it,

564
00:45:27.880 --> 00:45:31.519
the better. And there's another I
said earlier. I had mentioned something specifically

565
00:45:31.519 --> 00:45:35.440
about the IO reading. I wrote
five schedule looks andy bit, it's a

566
00:45:35.440 --> 00:45:40.079
good opportunity to touch that. So
then Ruby, there are operations like reading

567
00:45:40.079 --> 00:45:45.039
and writing from a socket or a
file or something, and you want that

568
00:45:45.119 --> 00:45:49.280
to be a concurrent and it turns
out that some of those operations are quite

569
00:45:49.320 --> 00:45:53.880
hard to do it concurrently, like
reading from a file concurrently, there's no

570
00:45:54.000 --> 00:46:00.559
good API for that and general Unix, if you try to say is the

571
00:46:00.599 --> 00:46:04.920
file readable, it will always say
yeah, it's readable, and it's unlike

572
00:46:04.920 --> 00:46:07.400
I, say a network socket,
which if the data hasn't come into the

573
00:46:07.440 --> 00:46:09.480
network card, then the socket is
not readable. But a file is always

574
00:46:09.519 --> 00:46:15.840
available to read, and so there's
no good mechanism for basically detecting their case.

575
00:46:15.079 --> 00:46:20.840
And so you get APIs like what's
called AIO, which lets your schedule

576
00:46:20.880 --> 00:46:23.800
operation be say I would like you
to read the data from this file and

577
00:46:23.840 --> 00:46:29.239
then tell me when it's done.
But these APIs have always been slightly plunky

578
00:46:29.239 --> 00:46:31.000
to use, and often that don't
work as effectively as you'd like. So

579
00:46:32.679 --> 00:46:39.119
there's a great new API called iouring
and ieuring actually is an asynchronous system called

580
00:46:39.760 --> 00:46:45.199
for Linux. So there's a whole
bunch of light system calls that by default

581
00:46:45.360 --> 00:46:47.119
synchronous, like the operating system will
take some time to do the operation,

582
00:46:47.519 --> 00:46:55.320
and there was no easy way to
do their operation in a non walking fashion.

583
00:46:55.320 --> 00:46:58.760
There was no API. There's no
way to say, can you start

584
00:46:58.760 --> 00:47:00.559
doing this? And then tell me
when it's done. There was no easy

585
00:47:00.559 --> 00:47:04.519
way to do that at the system
call level, and so what the ie

586
00:47:04.599 --> 00:47:08.159
you ring is is it's it's a
buffer, a submission buffer and a completion

587
00:47:08.239 --> 00:47:10.360
buffer. And what you do is
when you want to do like a system

588
00:47:10.360 --> 00:47:15.519
calls specific system call, you basically
write all the details of that system call

589
00:47:15.519 --> 00:47:19.519
into the submission buffer and then the
operating system will basically just read along that

590
00:47:19.559 --> 00:47:22.039
submission buffer, taking out the operations
and then doing them. And when the

591
00:47:22.119 --> 00:47:25.239
operation is completed, it will put
the result of the operation into the completion

592
00:47:25.320 --> 00:47:30.800
buffer. And so you have instead
of having synchronous system calls, you now

593
00:47:30.840 --> 00:47:35.199
have asynchronous system calls right And as
time goes on, more and more operations

594
00:47:35.239 --> 00:47:38.119
are being added to URINE. So
it's really exciting because it allows us to

595
00:47:38.159 --> 00:47:42.639
do things like one of the ones, like a simple example of where there

596
00:47:42.679 --> 00:47:46.920
was no asynchronous version if allocate,
which basically allocates a file on disc and

597
00:47:47.000 --> 00:47:51.880
this can take time and it's a
blocking operation potentially. So if you want

598
00:47:51.880 --> 00:47:55.519
to create like a thirty gigabyte file
on disc, use if allocate to allocate

599
00:47:55.559 --> 00:47:59.320
the spacefully start writing to it,
otherwise you might get halfway through and you

600
00:47:59.360 --> 00:48:04.599
can't writing more data out of mimerica
or something. Now with I you ring,

601
00:48:04.639 --> 00:48:07.840
you can schedule this operation into the
ur ring and then you can wait

602
00:48:07.840 --> 00:48:09.880
for it to complete in the background. And so this is really fantastic for

603
00:48:10.039 --> 00:48:16.000
the fiber scheduler because the fiber scheduler
can take more and more operations. And

604
00:48:16.039 --> 00:48:20.559
in this particular case, I read
and I writ are examples of those operations

605
00:48:20.599 --> 00:48:23.840
where you can may see, hey, read from this file and when the

606
00:48:23.880 --> 00:48:31.559
operation is complete, tell me that
it's done right to the operating system instead

607
00:48:31.559 --> 00:48:36.320
of trying to manage it itself exactly. And so I'm really excited by this

608
00:48:36.400 --> 00:48:39.039
functionality and it works as off to
day life. You use the last version

609
00:48:39.079 --> 00:48:43.320
of acink, you get I support
and links where it's where it's supported.

610
00:48:45.280 --> 00:48:47.440
And again, like it's it's a
complex system. There will be issues to

611
00:48:47.480 --> 00:48:52.320
work out, but we are solving
those problems and we're seeing significant advantages in

612
00:48:52.360 --> 00:49:00.960
production with these types of interfaces.
So I think, yeahs original question like

613
00:49:00.000 --> 00:49:04.360
what is the future of Ruby,
I think there's two pieces. There's the

614
00:49:04.440 --> 00:49:07.480
catcher, which whereas like things like
web sockets should have been better at earlier

615
00:49:07.519 --> 00:49:12.360
on and I think basink solves part
of those problems, and then there's just

616
00:49:12.400 --> 00:49:19.199
adoption of like user adoption, but
then there's also exciting things like have Ruby

617
00:49:19.199 --> 00:49:22.559
actually interfaces with the operating system to
do things more efficiently, and the low

618
00:49:22.679 --> 00:49:29.880
level interfaces and hooks and just like
design required to do that, and hopefully

619
00:49:29.920 --> 00:49:31.480
like most of that's hidden from the
end user, so you just install a

620
00:49:31.559 --> 00:49:37.239
new version of Ruby and things work
better. And so for me personally,

621
00:49:37.239 --> 00:49:40.039
that's what I'm focused on and where
I think I want to spend more of

622
00:49:40.079 --> 00:49:45.079
my time. Very cool. Well, we're over the forty five minutes that

623
00:49:45.119 --> 00:49:50.239
we have scheduled, and I have
a whole bunch here at tew on.

624
00:49:50.639 --> 00:49:53.000
Plus we're also scheduled to do a
Ruby Rogues episode coming up soon, so

625
00:49:54.920 --> 00:49:58.000
you know, we can go into
more detail there. But this has been

626
00:49:58.039 --> 00:50:02.360
really fascinating. Thanks for coming and
talking through this. It's a little bit

627
00:50:02.360 --> 00:50:06.679
different angle on the future Ruby than
kind of what I've gotten from other folks,

628
00:50:06.719 --> 00:50:08.840
and so hopefully some people dive in
and go, oh, well,

629
00:50:08.840 --> 00:50:12.960
maybe I can help with that,
or oh I'd really like to understand that

630
00:50:13.000 --> 00:50:15.159
more if they do want to reach
out to you on that stuff. How

631
00:50:15.159 --> 00:50:20.480
do they find you online? The
best way to do it is get have

632
00:50:20.639 --> 00:50:22.679
discussions. So I'm good, I'm
good. Any of the projects you're interested

633
00:50:22.679 --> 00:50:25.119
in, just find the discussions and
if it's not enabled, just pring me

634
00:50:25.159 --> 00:50:30.079
on, bring me on the other
discussions. Most of the major projects have

635
00:50:30.119 --> 00:50:32.760
discussions enabled, and it's a great
place because there's a bunch of people who

636
00:50:34.039 --> 00:50:38.800
get involved and have experienced using it
and can help some questions. Yeah,

637
00:50:38.920 --> 00:50:44.480
okay, sounds good. Well we'll
go ahead and wrap up here. Thank

638
00:50:44.519 --> 00:50:46.840
you so much time folks the opportunity
to talk as well. Oh thanks for

639
00:50:46.880 --> 00:50:51.920
coming. This is like I said, this has been really really fascinating and

640
00:50:51.960 --> 00:50:52.760
yeah, until next time, folks. Max out

