WEBVTT 00:00.000 --> 00:12.200 So now we have Glenn, he's going to talk about his project of Rama and yeah, it looks like 00:12.200 --> 00:16.000 he's going to be really good talk, so give me a welcome please. 00:16.000 --> 00:24.000 Okay, first of all, does everybody hear me? 00:25.000 --> 00:31.000 Okay, super. Before we begin, did anybody hear already hear about Rama? 00:31.000 --> 00:34.000 Or is it the first time a one person? 00:34.000 --> 00:35.000 That's something. 00:35.000 --> 00:45.000 So Rama is made by myself and the company I co-founded and we mainly built the company to 00:45.000 --> 00:47.000 fund our open source work. 00:47.000 --> 00:53.000 As most of our work is open source and freely available in the MIT licenses, 00:53.000 --> 00:59.000 because we believe that there needs to be better software to be easier building network 00:59.000 --> 01:00.000 stacks. 01:00.000 --> 01:03.000 And we will talk about that in this conversation. 01:03.000 --> 01:07.000 So we also have a podcast about networking and rust. 01:07.000 --> 01:10.000 In case you like the subject, I imagine you are in the rust track. 01:10.000 --> 01:15.000 And the reason I bring it up is because we don't only want to like develop software. 01:15.000 --> 01:21.000 We also want to educate people around rust and networking because for too many in the 01:21.000 --> 01:24.000 software industry, networking is still a mystery. 01:24.000 --> 01:29.000 Even if you would try to write back-and-services, you might never have, 01:29.000 --> 01:35.000 yeah, read the protocol RFCs or then how they work or even make the best use of it possible. 01:35.000 --> 01:40.000 So in case you like networking a rust, I would tell you you might want to listen to the podcast. 01:40.000 --> 01:44.000 And in case you do not work, I want to have a small interview after this conversation 01:44.000 --> 01:46.000 do catch me outside. 01:47.000 --> 01:50.000 So we develop Rama, it's on Gipter, it's MIT license. 01:50.000 --> 01:54.000 And it's a modular service framework to move and transform packets. 01:54.000 --> 01:59.000 So we're going to try to unpack that tagline in this talk. 01:59.000 --> 02:01.000 So why Rama? 02:01.000 --> 02:07.000 That is the first question because of course it's not like it's the only framework around building network stacks 02:07.000 --> 02:08.000 or why another one. 02:08.000 --> 02:12.000 And the honest answer is I wish I wouldn't have to write it. 02:12.000 --> 02:15.000 Because it's the last three, four years. 02:15.000 --> 02:17.000 There was a lot of time, so I'm going into. 02:17.000 --> 02:20.000 But I feel I know the choice and I will tell you why. 02:20.000 --> 02:26.000 So you can, if you want to build network stacks, either use something that is of the 02:26.000 --> 02:27.000 shelf working. 02:27.000 --> 02:33.000 So meaning like something like ng and x or maybe you use MIT and proxy, 02:33.000 --> 02:36.000 if you build proxies, there are all kinds of things. 02:36.000 --> 02:38.000 And you might try to plug in for them. 02:38.000 --> 02:41.000 You might try, yeah, ways to extend them. 02:41.000 --> 02:45.000 But you're always, first of all, it's very implicit. 02:45.000 --> 02:48.000 So you don't really know often how the flow is going. 02:48.000 --> 02:51.000 What the lifetime of the request is, what you can do. 02:51.000 --> 02:57.000 And even though it might give you strong velocity at start because it has a lot for you already. 02:57.000 --> 03:03.000 You will quite quickly run to a wall, once you build up your service more or more. 03:03.000 --> 03:06.000 As you build up new features and the complexity at up, 03:06.000 --> 03:11.000 you will soon or later start to fight against your own tooling and your velocity will drop. 03:11.000 --> 03:15.000 The other choice you have, and that's the one I also choose in the past often. 03:15.000 --> 03:19.000 Next to having written an engine x before, is you rise from scratch. 03:19.000 --> 03:24.000 And of course when I mean writing from scratch, I don't mean you start from nothing. 03:24.000 --> 03:27.000 You will probably use some like low level networking library. 03:27.000 --> 03:32.000 If you use risk time, sure there are a couple you can think of and see there are other ones. 03:32.000 --> 03:38.000 But the problem with that is that each time you do this, be it for a customer or for your own product, 03:38.000 --> 03:42.000 you each time again run in very similar issues and books. 03:42.000 --> 03:46.000 Because while the protocols themselves are very easy, 03:46.000 --> 03:50.000 it is very tricky to get them right once you combine them. 03:50.000 --> 03:57.000 And once you throw in around 50,000 or 100,000 requests per second on these kind of services, 03:57.000 --> 04:01.000 you quite quickly run into all kinds of applications which you didn't foresee. 04:01.000 --> 04:04.000 And I've been doing that for around eight years or more. 04:04.000 --> 04:09.000 And it became very tiring because first of all you have like a very low velocity at the start. 04:09.000 --> 04:13.000 And secondly, you each time like a set run in the same issues. 04:13.000 --> 04:19.000 The only nice thing about writing from scratch is that you do have the ultimate freedom to do what you want. 04:19.000 --> 04:24.000 But the downside is that you just reinventing the village time. 04:24.000 --> 04:31.000 And so, while I also like about the ability to write from scratch or that approach, 04:31.000 --> 04:38.000 even though I wouldn't recommend it, is that you can write in the way where the flow is very explicit. 04:38.000 --> 04:45.000 Because if we go back to the of the south regions like NGNX or very similar technologies to me, 04:45.000 --> 04:51.000 it is not always clear how a request flows through which middleware, through which plugin, 04:51.000 --> 04:55.000 especially won't you start to write more and more dynamic plugins in CEO or whatever. 04:55.000 --> 05:00.000 Like it's very unclear, like how your request flows and when some weird issues happen, 05:00.000 --> 05:06.000 in some kind of network stack layer, be it TCP, UDP, NHDP, doesn't really matter. 05:06.000 --> 05:09.000 You really have to stretch your head to find where the issue is. 05:09.000 --> 05:15.000 So, with Rama, we really wanted to have something that won't really read the code, 05:15.000 --> 05:20.000 that you write yourself with Rama, that you also understand how the packets flow. 05:20.000 --> 05:27.000 So, if you look, for example, at an example of such a stack, this is an example of a service stack, 05:27.000 --> 05:34.000 which is combining TCP and on top of that, we use Sox5 or HTTP, like both proxy protocols, 05:34.000 --> 05:39.000 would be supported in this stack, and it is also optionally with TLS, 05:39.000 --> 05:45.000 and it is like a little proxy that then proxies the either plain text traffic or the encrypted traffic, 05:45.000 --> 05:48.000 but it leaves that encrypted. 05:48.000 --> 05:53.000 And while it might be with daunting at first, the flow is very clear. 05:53.000 --> 05:58.000 Like even though you don't or not an expert in, let's say, the framework, 05:58.000 --> 06:03.000 if you take some time to reach through it from bottom to upper or up to bottom, 06:03.000 --> 06:06.000 it will make sense how the flow is. You don't have to guess it. 06:06.000 --> 06:08.000 You don't have to look in some documentation. 06:08.000 --> 06:11.000 Is it going first, you have this middle layer or if you have that middle layer, 06:11.000 --> 06:15.000 is the ordering like this or like that, you can just read it. 06:15.000 --> 06:19.000 But I do understand that it will look a bit daunting, 06:19.000 --> 06:23.000 but that's simply the nature of the complexity of network stacks. 06:23.000 --> 06:29.000 So we are not, of course, invented in a vacuum, we are built on the shoulders of giants, 06:29.000 --> 06:35.000 and in our case, we built in the philosophy of towers, 06:35.000 --> 06:39.000 and tower itself was built on top of the philosophy of something else. 06:39.000 --> 06:42.000 And that means that everything around is basically a service. 06:42.000 --> 06:45.000 So you get an input and you give back an output or an error. 06:45.000 --> 06:47.000 And of course, in case you have no error in reverse, 06:47.000 --> 06:50.000 you can use something like infallible, that also works. 06:50.000 --> 06:54.000 And everything that you want to layer be at the laser HTTP or whatever, 06:54.000 --> 06:56.000 will just layer on top of each other. 06:56.000 --> 06:58.000 And this way, you can combine them like Lego blocks, 06:58.000 --> 07:02.000 and have the absolute freedom of your network stack. 07:02.000 --> 07:05.000 The service trade currently looks like this. 07:05.000 --> 07:08.000 If you ever have seen tower, it will look very similar. 07:08.000 --> 07:11.000 So you have to define an output, you have to define an error. 07:11.000 --> 07:14.000 And you have to define, of course, the serve function. 07:14.000 --> 07:16.000 You don't always have to define this yourself, 07:16.000 --> 07:18.000 or implement this straight yourself. 07:18.000 --> 07:20.000 There are other ways to get the same service, 07:20.000 --> 07:23.000 be it with a function or be it as something else, 07:23.000 --> 07:26.000 like static response or something. 07:26.000 --> 07:29.000 And then because of how risk and the status today, 07:29.000 --> 07:32.000 we also need to provide something to provide the box service, 07:32.000 --> 07:35.000 because we already used implementation, 07:35.000 --> 07:37.000 return type for the trades, 07:37.000 --> 07:40.000 and that is currently a bit wonky in the rest state as it is. 07:40.000 --> 07:42.000 But we did want to make use of it, 07:42.000 --> 07:45.000 and so we were very happy that it shipped as part of the 2024 edition, 07:45.000 --> 07:49.000 as we've been following risks since the very early days, 07:49.000 --> 07:51.000 like around 10 years ago. 07:51.000 --> 07:55.000 Now, as I said, we didn't invent this service concept. 07:55.000 --> 07:59.000 As far as I remember, it was a phenical, 07:59.000 --> 08:01.000 who first came up with it at Twitter, 08:01.000 --> 08:04.000 and maybe even before, but I remember in 2011, 08:04.000 --> 08:08.000 they made an announcement that they started using phenical, 08:08.000 --> 08:11.000 which was in Java, if I recall correctly, 08:11.000 --> 08:15.000 and then later in Rust, there was the folks of tower or S. 08:15.000 --> 08:19.000 They made tower, and it looked, 08:19.000 --> 08:21.000 I mean, they took a lot of the knowledge from phenical, 08:21.000 --> 08:24.000 and made it in a more like Rust way. 08:24.000 --> 08:29.000 The Rust of 2016 is very different than Rust is today. 08:29.000 --> 08:33.000 Back then, there were no easy ways to do a synchronous code in Rust, 08:33.000 --> 08:36.000 and most didn't even attempt to do it. 08:36.000 --> 08:39.000 And so you can also see it in how tower is built. 08:39.000 --> 08:43.000 On top of that, they made some choices that we find regrettable, 08:43.000 --> 08:48.000 such as the fact that they made it very conscious choice 08:48.000 --> 08:51.000 to add something like pull ready in their service trade, 08:51.000 --> 08:55.000 which means even though it's a kind of function that you need, 08:55.000 --> 08:58.000 in case you want to check if a service is ready, 08:58.000 --> 09:02.000 and it might be needed because you want to load balancing 09:02.000 --> 09:05.000 or shedding or whatever, but it's a very niche use case, 09:05.000 --> 09:08.000 or many ways to do it also even if you don't have an explicit function. 09:08.000 --> 09:14.000 And next to that, in case you want to ever not make the function mutable, 09:14.000 --> 09:17.000 it is also a very wonky contract to get right. 09:17.000 --> 09:22.000 So we then, in 2018, start the experiment with something called tower or sink, 09:22.000 --> 09:27.000 as at that time, in nightly, all the things that we wanted were available, 09:27.000 --> 09:31.000 and that is what you see below the tower implementation. 09:31.000 --> 09:34.000 So we dropped the pole ready, and we started to return futures, 09:35.000 --> 09:39.000 and then between 2024 and 2006, we started to develop Rama 09:39.000 --> 09:45.000 after we have done several iterations on our several experiments and MPPs. 09:45.000 --> 09:48.000 And that is currently how the trade is today. 09:48.000 --> 09:52.000 So we also renamed the request and response to input and output, 09:52.000 --> 09:55.000 because in Rama everything is a service, 09:55.000 --> 09:59.000 and so even your TCP service, or your UDP service, your TLS service, 09:59.000 --> 10:02.000 your SOx5, your H Proxy, it doesn't really matter. 10:02.000 --> 10:05.000 There are all services that you stack on top of each other, 10:05.000 --> 10:09.000 in a way that you want and in a way that works for your project. 10:09.000 --> 10:13.000 So as I said, you can see several examples for TCP, 10:13.000 --> 10:16.000 it means that you are getting a TCP stream, 10:16.000 --> 10:19.000 and you just return nothing because you are serving the entire stream. 10:19.000 --> 10:22.000 For TLS, you will get some kind of stream, 10:22.000 --> 10:25.000 it doesn't have to be TCP, it can also be UDP or whatever kind of stream it is. 10:25.000 --> 10:28.000 It just needs to be a stream that gives you bytes, 10:28.000 --> 10:32.000 and then HTTP will start from a byte stream that's your server, 10:32.000 --> 10:34.000 but then you also have an HTTP service, 10:34.000 --> 10:36.000 which actually deals with the requests. 10:36.000 --> 10:37.000 And once you read that layer, 10:37.000 --> 10:41.000 it doesn't really matter anymore if it HTTP 2 or HTTP 3 or whatever. 10:41.000 --> 10:45.000 At that point, it's just a generic kind of request. 10:45.000 --> 10:49.000 So if we now go back to the original slides, 10:49.000 --> 10:51.000 where I showed you an example stack, 10:51.000 --> 10:53.000 which you can also find in our examples, 10:53.000 --> 10:55.000 and I will talk a bit about Rama examples later, 10:56.000 --> 10:58.000 is that you can see indeed, 10:58.000 --> 11:01.000 that we have a kind of protocol, 11:01.000 --> 11:03.000 the layers nicely on top of each other. 11:03.000 --> 11:07.000 However, and that is the first thing that I noticed, 11:07.000 --> 11:11.000 and it might be because some people didn't work a lot with Rost before, 11:11.000 --> 11:13.000 but one thing I see a lot is then, 11:13.000 --> 11:16.000 you get into, and as not only Rama, 11:16.000 --> 11:20.000 I also saw it in other communities like in Axium and in Towers, 11:20.000 --> 11:24.000 is that they start to get very huge stacks of generics, 11:24.000 --> 11:26.000 and they try to label them. 11:26.000 --> 11:28.000 So for example, for this stack, 11:28.000 --> 11:30.000 that is the entire type, 11:30.000 --> 11:32.000 and it's very painful, and in fact, 11:32.000 --> 11:35.000 it's only painful because you try to label it. 11:35.000 --> 11:38.000 And I would think it's kind of like trying to label 11:38.000 --> 11:40.000 every part of your house, 11:40.000 --> 11:41.000 like you wouldn't do that. 11:41.000 --> 11:43.000 You might define some properties of your house, 11:43.000 --> 11:45.000 but you're not going to define every little 11:45.000 --> 11:48.000 cranny and who can detail of your house. 11:48.000 --> 11:50.000 So instead, you have to think about, 11:50.000 --> 11:52.000 what is the actual service doing? 11:52.000 --> 11:54.000 For example, in this case, or stack, 11:54.000 --> 11:57.000 was a proxy stack, which was a man in the middle 11:57.000 --> 12:00.000 in HTTP traffic via the other encryption notes, 12:00.000 --> 12:03.000 and so we really just want a TCP stream at input, 12:03.000 --> 12:06.000 and we want an error in case something really horrible and wrong, 12:06.000 --> 12:10.000 or otherwise nothing because we were just finished with serving this stream. 12:10.000 --> 12:14.000 And in that way, you have to think in terms of trade bonds, 12:14.000 --> 12:16.000 because one should start to that, 12:16.000 --> 12:18.000 then you have two options. 12:18.000 --> 12:21.000 Either you have your functions or your structure or whatever, 12:21.000 --> 12:24.000 where you take a generic parameter like a single one, 12:24.000 --> 12:26.000 and you just define what you want. 12:26.000 --> 12:28.000 Be it, okay, for example, in this case, 12:28.000 --> 12:31.000 I want the service, which takes an HTTP request, 12:31.000 --> 12:33.000 and it returns an HTTP response, 12:33.000 --> 12:36.000 and the error needs to be something that some kind of standard error 12:36.000 --> 12:38.000 or can be turned into that. 12:38.000 --> 12:41.000 Or in case you don't want to deal with generics, 12:41.000 --> 12:43.000 because the thing with generics is that they're very leaky, 12:43.000 --> 12:46.000 and once you start to introduce them to your struct, 12:46.000 --> 12:48.000 for functions as less of an issue, 12:48.000 --> 12:50.000 because you rarely ever have to define them, 12:50.000 --> 12:52.000 but for structs they can be leaky, 12:52.000 --> 12:54.000 and in case you need to pause them around 12:54.000 --> 12:55.000 to several locations, 12:55.000 --> 12:58.000 you might as that want to choose for dynamic dispatching. 12:58.000 --> 13:00.000 And that is the same thing, 13:00.000 --> 13:02.000 because your trade bonds still looks the same. 13:02.000 --> 13:04.000 The only difference is that you boxed it, 13:04.000 --> 13:05.000 and in an OR case, 13:05.000 --> 13:07.000 we didn't box it to be octed, 13:07.000 --> 13:09.000 as dynamic dispatched trades. 13:09.000 --> 13:12.000 Now, around case and simplicity, 13:12.000 --> 13:15.000 and also, of course, and being explicit. 13:15.000 --> 13:17.000 This wasn't like a very easy road, 13:18.000 --> 13:21.000 and a similar road that's finished far from it. 13:21.000 --> 13:23.000 Like we are now trees and developments, 13:23.000 --> 13:26.000 and I feel given how many network protocols there are, 13:26.000 --> 13:28.000 or many different use cases there are, 13:28.000 --> 13:32.000 I might still be doing this for decades to come. 13:32.000 --> 13:35.000 So far, we already have more and more companies adopting Rama, 13:35.000 --> 13:38.000 and this tells us a lot about how to improve Rama, 13:38.000 --> 13:40.000 and what to add next. 13:40.000 --> 13:44.000 Some of these, which we thought of initially as working fine, 13:44.000 --> 13:47.000 they're not to be too complex or too niche, 13:47.000 --> 13:51.000 very similar to how we observed the pull ready function, 13:51.000 --> 13:54.000 to be too niche over use case, 13:54.000 --> 13:56.000 to warn that kind of complexity. 13:56.000 --> 13:58.000 And so I want to give you a couple of examples, 13:58.000 --> 14:00.000 because at Plabayo, 14:00.000 --> 14:02.000 we really want to develop software that works for you, 14:02.000 --> 14:05.000 and that's not in your way. 14:05.000 --> 14:08.000 So here are a couple of examples. 14:08.000 --> 14:10.000 If you take a service, 14:10.000 --> 14:12.000 and you need to have it cloned, 14:12.000 --> 14:14.000 because you need to pass it through different threats, 14:14.000 --> 14:17.000 you could implicitly market for the users. 14:17.000 --> 14:19.000 And that's something we did at some locations at the start, 14:19.000 --> 14:21.000 because it made it very easy, 14:21.000 --> 14:23.000 or it made sense at that point of time. 14:23.000 --> 14:25.000 I don't remember any more, 14:25.000 --> 14:29.000 but as we are cleaning up more and more of these kind of initial choices, 14:29.000 --> 14:31.000 I find it a much better choice to instance, 14:31.000 --> 14:34.000 ask the service needs to be a service, 14:34.000 --> 14:35.000 but it also needs to be cloneable. 14:35.000 --> 14:37.000 If the user wants to market, that's fine, 14:37.000 --> 14:40.000 but it needs to be a choice of the users, 14:40.000 --> 14:44.000 or the choice of the thing the user is using. 14:44.000 --> 14:48.000 Similarly, we have the philosophy of everything as a service, 14:48.000 --> 14:51.000 but still we had sometimes specialized traits 14:51.000 --> 14:53.000 to do something specific. 14:53.000 --> 14:55.000 An example of that was the request inspector, 14:55.000 --> 14:57.000 and it kind of does what the name does. 14:57.000 --> 14:59.000 It is kind of like a service, 14:59.000 --> 15:00.000 but it takes a request, 15:00.000 --> 15:02.000 and it returns a modified request. 15:02.000 --> 15:05.000 And it's a very kind of niche use case, 15:05.000 --> 15:06.000 but it did work out, 15:06.000 --> 15:07.000 and it made it another time. 15:07.000 --> 15:11.000 But again, as we start to clean up our code base, 15:11.000 --> 15:13.000 and get more and more traction in production, 15:13.000 --> 15:15.000 we also wanted things to be simple, 15:15.000 --> 15:17.000 because there was already sufficiently things to learn. 15:17.000 --> 15:20.000 Why should use more complexity for the users? 15:20.000 --> 15:22.000 And so we removed that, 15:22.000 --> 15:24.000 and now these things are just, of course, a service, 15:24.000 --> 15:27.000 because you can just modify your request 15:27.000 --> 15:30.000 and leave the response, and it ends the same. 15:30.000 --> 15:33.000 Another example is something called a context. 15:33.000 --> 15:36.000 So initially, the service didn't just take input, 15:36.000 --> 15:38.000 but it also kind of context. 15:38.000 --> 15:42.000 And the idea behind that was to make statically type states, 15:42.000 --> 15:46.000 pass around, but it turns out that it is a very niche use case, 15:46.000 --> 15:49.000 and in the only location you really want this, 15:49.000 --> 15:51.000 is in some kind of servers. 15:51.000 --> 15:53.000 And so now you can still do these things, 15:53.000 --> 15:54.000 and of course you could always do these things, 15:54.000 --> 15:56.000 because services can be structs, 15:56.000 --> 15:58.000 and so you always have the option 15:58.000 --> 16:01.000 to make your own struct implement service traits, 16:01.000 --> 16:02.000 and add state to it. 16:02.000 --> 16:05.000 But in case you want to have something like a function, 16:05.000 --> 16:08.000 as your router, in case you write an HTTP stack, 16:08.000 --> 16:11.000 then we allow the things in the router to have a state, 16:11.000 --> 16:15.000 and we pause them via a trade bound, 16:15.000 --> 16:18.000 and then you are statically type state still works, 16:18.000 --> 16:20.000 but it is a very niche use case, 16:20.000 --> 16:23.000 and it is very located for this kind of use case, 16:23.000 --> 16:26.000 and we don't have to leak it through the entire thing. 16:26.000 --> 16:28.000 Sometimes you do have dynamic states, 16:28.000 --> 16:29.000 and for that we have extensions. 16:29.000 --> 16:33.000 So both inputs and outputs kind of extensions, 16:33.000 --> 16:35.000 and you can think of that for your so-called addresses, 16:35.000 --> 16:38.000 for dynamic behavior, maybe you want to disable IPv4, 16:38.000 --> 16:40.000 maybe you want to override the NS. 16:40.000 --> 16:42.000 There are all kinds of things that you might want to plug in, 16:42.000 --> 16:45.000 and at your middleware, including your own middleware, 16:45.000 --> 16:46.000 good react to. 16:46.000 --> 16:48.000 That's what extensions are for. 16:48.000 --> 16:51.000 And so for now it's influx, 16:51.000 --> 16:53.000 because we are improving it once again. 16:53.000 --> 16:56.000 But at the moment, this is having two traits on the inputs, 16:56.000 --> 16:59.000 and the outputs, which is like you can take them by reference, 16:59.000 --> 17:01.000 taking them by a multiple pointer, 17:01.000 --> 17:04.000 but in the future you will only need to do it by reference, 17:04.000 --> 17:09.000 because we just finished implementing an append-only vector, 17:09.000 --> 17:14.000 which allows us to pass only by single shared reference, 17:14.000 --> 17:16.000 and don't have to worry about a mutation. 17:16.000 --> 17:18.000 But the point being, 17:18.000 --> 17:21.000 is you can inject any kind of dynamic state into it, 17:21.000 --> 17:23.000 and the only unique thing is to put its sockets, 17:23.000 --> 17:27.000 all the way to your final application handling of the response, 17:27.000 --> 17:29.000 whatever protocols you go through, 17:29.000 --> 17:32.000 they all change these extensions as they go, 17:32.000 --> 17:34.000 and they leave little breadcrumbs, 17:34.000 --> 17:36.000 as what choices we're made, 17:36.000 --> 17:39.000 and what behavior has to have dynamically be changed. 17:39.000 --> 17:41.000 So Rama is a proxy, 17:41.000 --> 17:44.000 but it's also not just a proxy framework, 17:44.000 --> 17:47.000 because a proxy is a server and a client. 17:47.000 --> 17:49.000 And so what I mean with that is, 17:49.000 --> 17:52.000 for example, if you look at a client or a server HTTP, 17:52.000 --> 17:55.000 and a mostly used HTTP here, 17:55.000 --> 17:57.000 because it's the protocol, 17:58.000 --> 18:00.000 but of course not just a HTTP, 18:00.000 --> 18:03.000 but if we continue to take an HTTP, 18:03.000 --> 18:05.000 you can see that the client and a server, 18:05.000 --> 18:07.000 they are pretty much the same signature. 18:07.000 --> 18:09.000 You take a request and you return a response, 18:09.000 --> 18:11.000 and that is a very powerful concept, 18:11.000 --> 18:13.000 once you get your hat around it, 18:13.000 --> 18:17.000 we'll call it kind of means that we can make any service, 18:17.000 --> 18:20.000 like a very highly level, 18:20.000 --> 18:22.000 by having a trade and extension trade, 18:22.000 --> 18:24.000 and it's also not the concept we invented, 18:24.000 --> 18:26.000 and extension trade is basically, 18:26.000 --> 18:28.000 from very generic bonds, 18:28.000 --> 18:30.000 be it like any service, 18:30.000 --> 18:32.000 and you give it some kind of capabilities. 18:32.000 --> 18:34.000 And this allows us, like in the left, 18:34.000 --> 18:35.000 you can see, 18:35.000 --> 18:36.000 to easily make a request, 18:36.000 --> 18:38.000 and this works on any service, 18:38.000 --> 18:41.000 meaning even if you want to test your web servers, 18:41.000 --> 18:44.000 you can just treat it as if it's a client, 18:44.000 --> 18:47.000 because everything is really just a service. 18:47.000 --> 18:51.000 So Rama is a bunch of crates, 18:51.000 --> 18:53.000 and it's only growing, 18:53.000 --> 18:55.000 but for users that use Rama, 18:55.000 --> 18:57.000 they will just use the mono create, 18:57.000 --> 19:00.000 which imports all the other ones behind feature flags. 19:00.000 --> 19:02.000 So we have things around crypto, 19:02.000 --> 19:03.000 TLS, 19:03.000 --> 19:04.000 around HTTP, 19:04.000 --> 19:05.000 web sockets, 19:05.000 --> 19:06.000 GRPC, 19:06.000 --> 19:07.000 which is double an HTTP, 19:07.000 --> 19:08.000 well, 19:08.000 --> 19:09.000 does not have to be, 19:09.000 --> 19:10.000 but in most cases it is, 19:10.000 --> 19:11.000 you have the NAS, 19:11.000 --> 19:12.000 you have transports, 19:12.000 --> 19:13.000 whatever. 19:13.000 --> 19:14.000 And this list is growing, 19:14.000 --> 19:15.000 as the needs of ourselves, 19:15.000 --> 19:18.000 and the needs of our customers grow. 19:18.000 --> 19:20.000 We also have other resources, 19:20.000 --> 19:21.000 such as the book, 19:21.000 --> 19:23.000 there you can learn more about 19:23.000 --> 19:25.000 or philosophies or patterns, 19:25.000 --> 19:27.000 maybe because you're new to networking, 19:27.000 --> 19:31.000 you can also learn about the different kind of proxies you can build, 19:31.000 --> 19:32.000 and of course, 19:32.000 --> 19:33.000 just to give you a taste, 19:33.000 --> 19:35.000 because in the end you kind of can build with yourself. 19:35.000 --> 19:37.000 We also have a CLI tool, 19:37.000 --> 19:39.000 we also have other things. 19:39.000 --> 19:40.000 One example, 19:40.000 --> 19:41.000 for example, 19:41.000 --> 19:42.000 in the book, 19:42.000 --> 19:43.000 you can read about errors, 19:43.000 --> 19:45.000 and the fact that you can attach context to it, 19:45.000 --> 19:47.000 which is something most people would use anyhow for, 19:47.000 --> 19:48.000 but in Rama, 19:48.000 --> 19:50.000 we have a mini version of that, 19:50.000 --> 19:52.000 which allows you to, 19:52.000 --> 19:55.000 to work with errors without having to add that, 19:55.000 --> 19:57.000 and other dependency to your list. 19:57.000 --> 19:59.000 We also have public services, 19:59.000 --> 20:01.000 where you can test your, 20:01.000 --> 20:02.000 some HTTP protocol, 20:02.000 --> 20:04.000 should you be implementing my client, 20:04.000 --> 20:05.000 or what do you want to see, 20:05.000 --> 20:08.000 how your traffic looks like on the LSTTP, 20:08.000 --> 20:09.000 or HTTP. 20:09.000 --> 20:11.000 We also have a fingerprinting service 20:11.000 --> 20:13.000 to do emulation of user agents. 20:13.000 --> 20:15.000 We have an IP service, 20:15.000 --> 20:17.000 and these are all freely available. 20:17.000 --> 20:19.000 You can check them out now. 20:19.000 --> 20:21.000 We also have a lot of examples, 20:21.000 --> 20:23.000 and we add more and more examples. 20:23.000 --> 20:24.000 All our examples are also tested, 20:24.000 --> 20:26.000 and I don't just mean they compile. 20:26.000 --> 20:29.000 We also actually test the behavior for every commit, 20:29.000 --> 20:31.000 and know that they will work as promised, 20:31.000 --> 20:34.000 including documentation on the top of the example, etc. 20:34.000 --> 20:38.000 Now, Rama has been going on for a long time, 20:38.000 --> 20:41.000 and so we are hoping to ship zero point three, 20:41.000 --> 20:43.000 somewhere in the next month, 20:43.000 --> 20:45.000 but of course that is to be seen. 20:45.000 --> 20:47.000 There are a couple of little things 20:47.000 --> 20:48.000 that we want to know before, 20:48.000 --> 20:50.000 but starting from that, 20:50.000 --> 20:52.000 we are a bit tired of having the long gaps 20:52.000 --> 20:55.000 between the releases and having many alpha versions. 20:55.000 --> 20:58.000 So we are now at a point where we are stable enough, 20:58.000 --> 21:01.000 that we want to start doing regular releases. 21:01.000 --> 21:03.000 We will still do maybe sometimes breaking changes, 21:03.000 --> 21:04.000 but there will be more frequent, 21:04.000 --> 21:06.000 instead of building up to a giant release, 21:06.000 --> 21:08.000 because if you still be on 0.2, 21:08.000 --> 21:10.000 and you have to then jump to 0.3, 21:10.000 --> 21:12.000 it's going to be really painful, 21:12.000 --> 21:14.000 unless you have the help from us. 21:15.000 --> 21:18.000 Our star history grew kind of like around the time 21:18.000 --> 21:21.000 that also our framework became more stable, 21:21.000 --> 21:25.000 but it's still very small compared to the people that uses. 21:25.000 --> 21:28.000 Some people work with us, but others not. 21:28.000 --> 21:31.000 For example, OpenAI, they use it also for their codecs. 21:31.000 --> 21:35.000 So if you use codecs then it's like a local network proxy built with Rama. 21:35.000 --> 21:37.000 We have fund this work. 21:37.000 --> 21:40.000 And of course sharing is caring. 21:40.000 --> 21:43.000 The final thing I want to mention about Rama 21:43.000 --> 21:46.000 is we really were tired of reinventing everybody, 21:46.000 --> 21:47.000 which is very different. 21:47.000 --> 21:49.000 And if everybody makes their own little island, 21:49.000 --> 21:51.000 it just doesn't work. 21:51.000 --> 21:54.000 And so that's, we welcome anybody in a community. 21:54.000 --> 21:56.000 We also do mentorship, et cetera. 21:56.000 --> 21:59.000 And so yeah, I don't think I have time for questions, 21:59.000 --> 22:03.000 but otherwise thank you very much for paying attention to my talk. 22:03.000 --> 22:06.000 And if you want to talk to me, you can meet me outside. 22:06.000 --> 22:16.000 Thank you.