[00:00.000 --> 00:11.000] Okay, now we have Nelson Vides with the actor model as a load testing framework. [00:11.000 --> 00:16.800] Give it up. [00:16.800 --> 00:17.800] Thank you very much. [00:17.800 --> 00:18.800] Thank you for coming. [00:18.800 --> 00:19.800] Let's get started. [00:19.800 --> 00:21.080] As you heard, I'm Nelson Vides. [00:21.080 --> 00:25.000] We only have so many minutes, so I'm not going to go deep into an introduction of who I am. [00:25.000 --> 00:26.000] Just ask me on the corridors. [00:26.000 --> 00:27.000] I love talking. [00:27.000 --> 00:35.000] I'm Senior Erlang Consultant for Erlang Solutions and Core Mongolian Developer, messaging back-end, [00:35.000 --> 00:36.000] different questions. [00:36.000 --> 00:37.000] Again, ask me on the corridors. [00:37.000 --> 00:39.000] I would love to talk about it. [00:39.000 --> 00:46.000] Let's start with an analogy, an intro, a catchy intro. [00:46.000 --> 00:51.000] Now let's see how the internet works. [00:51.000 --> 00:56.000] While this loads, and I hope it loads, otherwise I have it downloaded, [00:56.000 --> 01:00.000] I had a fantastic teacher in high school, a fantastic physics teacher, [01:00.000 --> 01:03.000] kudos to him, whatever he is, hello. [01:03.000 --> 01:08.000] When we were studying aerodynamics and the Newton laws, [01:08.000 --> 01:11.000] we studied this bridge that is not loading. [01:11.000 --> 01:28.000] I think I will just save time and reproduce it here. [01:28.000 --> 01:32.000] Don't ask me how to make it bigger. [01:32.000 --> 01:38.000] Back in the 40s, they built a bridge in the Tacoma Narrows in Washington State, [01:38.000 --> 01:42.000] crossing from Tacoma to the peninsula, the other side of the Narrows, [01:42.000 --> 01:44.000] and the bridge had that problem. [01:44.000 --> 01:46.000] It had a very spectacular build. [01:46.000 --> 01:48.000] Through the build, they already realized that this is happening, [01:48.000 --> 01:54.000] that the bridge is not really stable, and very shortly after the grand opening, [01:54.000 --> 01:57.000] they had to evacuate. [01:57.000 --> 02:00.000] They left one car with the only casualty. [02:00.000 --> 02:06.000] Unfortunately, a dog was left inside of that car, the only casualty of this accident. [02:06.000 --> 02:11.000] This spectacular happening, if you check it on Wikipedia, [02:11.000 --> 02:16.000] it will be written that something like this left a mark in the history of engineering, [02:16.000 --> 02:22.000] engineers went all mad and crazy, what happened here, what mistake have we made? [02:22.000 --> 02:27.000] Eventually, the bridge fell in 1940, so then there was World War II, [02:27.000 --> 02:29.000] they didn't have a chance to build it. [02:29.000 --> 02:31.000] In the 50s, they built a new one. [02:31.000 --> 02:38.000] The old one, these pieces that fell are now a fantastic house for fishes in the bottom of the river. [02:38.000 --> 02:42.000] Let's go back to the presentation. [02:42.000 --> 02:50.000] Yeah, this never loaded, good that I don't load it. [02:50.000 --> 02:52.000] Why am I talking about this bridge? [02:52.000 --> 02:54.000] Back in the days, bridges were like this. [02:54.000 --> 02:58.000] In the Roman times, it was a solid piece of stone, [02:58.000 --> 03:01.000] you could just hammer it in all directions, it was just solid. [03:01.000 --> 03:03.000] What is the load that this bridge was having? [03:03.000 --> 03:07.000] A few Roman centurions walking, a hundred of them at a time. [03:07.000 --> 03:08.000] How heavy that is? [03:08.000 --> 03:11.000] Some armory, what armors they had anyway? [03:11.000 --> 03:16.000] It was not like big modern missiles and things that weighed tons. [03:16.000 --> 03:20.000] But one day, we went from bridges like that to bridges like this, [03:20.000 --> 03:22.000] that are very lightweight. [03:22.000 --> 03:26.000] Even if they are much bigger and they spawn way longer distances, [03:26.000 --> 03:30.000] they are way lighter than the previous one and they are not as solid. [03:30.000 --> 03:35.000] So there are forces that didn't used to matter in the previous bridge, [03:35.000 --> 03:38.000] that now make a really big difference. [03:38.000 --> 03:39.000] For example, wind. [03:39.000 --> 03:43.000] The previous bridge put it through a hurricane, [03:43.000 --> 03:46.000] probably like what kind of hurricane you need to do something. [03:46.000 --> 03:50.000] But that bridge, not this one in the picture, this is a model, [03:50.000 --> 03:54.000] but the Tacoma bridge fell under a wind of 40 miles per hour. [03:54.000 --> 03:58.000] It's not that I like miles, sorry, I'm supporter of the international system, [03:58.000 --> 04:01.000] but the Wikipedia article was written by an American, so it's in miles. [04:01.000 --> 04:04.000] How many kilometers per hour that is, I don't know how to convert it. [04:04.000 --> 04:07.000] But it's not a lot, it's not a hurricane. [04:07.000 --> 04:14.000] So my analogy, in the previous bridge, [04:14.000 --> 04:19.000] there was just a few people with a small load and forces that were there, [04:19.000 --> 04:21.000] didn't play any difference whatsoever. [04:21.000 --> 04:25.000] But in the new bridge, there is hundreds of cars with lots of loads, [04:25.000 --> 04:30.000] probably transports of goods and much bigger weapons than in the past, [04:30.000 --> 04:35.000] and forces that were always there really make a huge difference. [04:35.000 --> 04:41.000] Let's have an analogy that matters to us here, we are not bridge engineers. [04:41.000 --> 04:44.000] Not long ago we had these huge computers, [04:44.000 --> 04:47.000] but you can probably just punch them and nothing would ever happen. [04:47.000 --> 04:50.000] If I punch this one, the presentation is over. [04:50.000 --> 04:55.000] That were used by just a few people with a few use cases. [04:55.000 --> 05:00.000] And then we went to this magic infrastructure of God knows what is going on, [05:00.000 --> 05:06.000] of lots of things put somewhere, used by millions of people, [05:06.000 --> 05:09.000] God knows what use case people are finding out. [05:09.000 --> 05:13.000] You know, you probably, you design your service with one or two use cases in mind, [05:13.000 --> 05:15.000] and then people surprise you. [05:15.000 --> 05:22.000] So, the questions again. [05:22.000 --> 05:24.000] What are all the interactions? [05:24.000 --> 05:28.000] There was one or two use cases, but one or two people now is the limit. [05:28.000 --> 05:32.000] What is the traffic capacity? [05:32.000 --> 05:36.000] In the Roman bridge, there was Centurion, an army, a small army, [05:36.000 --> 05:38.000] a division with a few weapons. [05:38.000 --> 05:40.000] Now, just imagine a modern bridge. [05:40.000 --> 05:42.000] What about the amplifying factors? [05:42.000 --> 05:46.000] The problem with the wind asked me in the Q&A or in the questions like the details [05:46.000 --> 05:48.000] of why this bridge fell. [05:48.000 --> 05:50.000] I love that story. [05:50.000 --> 05:55.000] There was a little bit of wind that amplified the movement to more than the bridge would support. [05:55.000 --> 05:57.000] This can happen also to us. [05:57.000 --> 05:59.000] Imagine a client sends a packet that is compressed. [05:59.000 --> 06:02.000] We decompress it and, you know, he sends half a kilobyte, [06:02.000 --> 06:05.000] but we decompress it and it's five gigas. [06:05.000 --> 06:07.000] And, you know, you run out of memory. [06:07.000 --> 06:09.000] What about amplifying factors? [06:09.000 --> 06:11.000] And what about all forces that didn't make any difference? [06:11.000 --> 06:13.000] For example, punching a computer. [06:13.000 --> 06:17.000] That now they really do. [06:17.000 --> 06:18.000] All right. [06:18.000 --> 06:21.000] Let's get with a little bit of terminology. [06:21.000 --> 06:25.000] I'm coming back to the title of my presentation. [06:25.000 --> 06:27.000] What is a framework? [06:27.000 --> 06:31.000] Here you have a bunch of copy-pasted definitions from different dictionaries. [06:31.000 --> 06:36.000] And Wikipedia is the first, which is not the best dictionary, but we all love it. [06:36.000 --> 06:42.000] Basically, probably you have an idea like Phoenix is a web framework, for example. [06:42.000 --> 06:48.000] It's a set of tools that gives you a way to build a system to solve a problem. [06:48.000 --> 06:54.000] In turn, what is a model? [06:54.000 --> 07:00.000] You can have a model of a bridge, but you cannot have a framework of a bridge. [07:00.000 --> 07:05.000] You have a framework to build a bridge and a model that represents the bridge. [07:05.000 --> 07:10.000] Again, some copy-pasted definitions from diverse dictionaries for you to enjoy. [07:10.000 --> 07:11.000] And ask me later. [07:11.000 --> 07:17.000] This model, in particular, is the inverted model of the catenarius of the Sagrada Familia. [07:17.000 --> 07:18.000] Again, ask me. [07:18.000 --> 07:21.000] I love this topic, but we are here to talk about Erlang. [07:21.000 --> 07:25.000] This is how Gaudí designed the Sagrada Familia. [07:25.000 --> 07:26.000] That is just about to finish any day now. [07:26.000 --> 07:27.000] Let's some data. [07:27.000 --> 07:30.000] We'll finish it. [07:30.000 --> 07:36.000] So we have a framework, a set of tools to solve a problem, and a model, a representation, [07:36.000 --> 07:41.000] a theoretical representation of your problem set. [07:41.000 --> 07:43.000] Testing and load. [07:43.000 --> 07:51.000] Testing, like kids go to school and they get a test, just to prove that they know what they're supposed to know. [07:51.000 --> 07:57.000] It's a process of making sure that things are doing what they're supposed to do, that they know their knowledge, [07:57.000 --> 07:59.000] that the software does what it's supposed to do, et cetera. [07:59.000 --> 08:00.000] And load. [08:00.000 --> 08:02.000] This is what Newton would probably love to call work. [08:02.000 --> 08:05.000] Again, thank you, physics teacher. [08:05.000 --> 08:10.000] Probably what Newton would love to call work is a mass of quantity of something that has to be worked on. [08:10.000 --> 08:22.000] Like, moved, or supported, or resisted against gravity, or wind, or transported in these virtual bridges of cables that we have under the ocean, et cetera. [08:22.000 --> 08:31.000] So load testing is testing that the software, a service, can handle the load that we are giving it. [08:31.000 --> 08:35.000] And how it behaves under different such quantities. [08:35.000 --> 08:43.000] So we have this roughly scheme of, like, three points of performance testing, of load testing, that you have to test. [08:43.000 --> 08:46.000] Performance is basically how fast your algorithm is, like, executed once. [08:46.000 --> 08:48.000] It takes 10 seconds, or 10 nanoseconds. [08:48.000 --> 09:01.000] It's the theoretical performance, but what happens when you make a lot of requests at the point where you expect your service to still be able, but not more than that. [09:01.000 --> 09:03.000] It depends on the hardware you deploy, your architecture. [09:03.000 --> 09:07.000] You expect that this should behave like this, and then you test it. [09:07.000 --> 09:11.000] And then you put more load and see how it dies. [09:11.000 --> 09:21.000] We have this luxury in IT that we can destroy our software, because we can just replicate it, build infinite copies. [09:21.000 --> 09:23.000] You know, the bridge guy would be very yellow. [09:23.000 --> 09:25.000] He cannot build two bridges to break one. [09:25.000 --> 09:27.000] He has no second chance. [09:27.000 --> 09:28.000] There is one bridge. [09:28.000 --> 09:29.000] Don't break it. [09:29.000 --> 09:30.000] It's very expensive. [09:30.000 --> 09:31.000] Make sure it works. [09:31.000 --> 09:37.000] How do you test what happens when it dies? [09:37.000 --> 09:46.000] So a load testing framework is going to be, of course, a set of tools that gives you a way to test these different kinds of loads. [09:46.000 --> 09:49.000] And for these kinds of loads, you need some units of measurement. [09:49.000 --> 09:51.000] What is a load? [09:51.000 --> 09:55.000] In the case of the bridge, Newton would love to call that the forces. [09:55.000 --> 09:58.000] And you need the interactions. [09:58.000 --> 10:01.000] How are these possible loads applied? [10:01.000 --> 10:08.000] You know, in the case of the bridge, we would usually think of gravity. [10:08.000 --> 10:09.000] There is just one interaction. [10:09.000 --> 10:12.000] It goes down, but wind and turbulence and your users can be very crazy. [10:12.000 --> 10:14.000] Forces can be applied in any way. [10:14.000 --> 10:20.000] So we need to think about the unit of measurement and the interactions. [10:20.000 --> 10:22.000] So as I said, there is the forces. [10:22.000 --> 10:24.000] Newton would love this. [10:24.000 --> 10:27.000] And the equivalent. [10:27.000 --> 10:31.000] You have a service, some backend that has users. [10:31.000 --> 10:38.000] And as I said before, you would never imagine the ways they find to use your service. [10:38.000 --> 10:43.000] You're usually designed with three or four things in mind, but you know. [10:43.000 --> 10:55.000] So I would say that the equivalent of the forces that can be applied in different directions are, like, [10:55.000 --> 10:57.000] self-independent programs. [10:57.000 --> 11:03.000] Imagine that each one of those users is a program that decides how to apply his force, [11:03.000 --> 11:05.000] decides how to interact. [11:05.000 --> 11:09.000] Like, each one of those many arrows that you can draw in this bridge, [11:09.000 --> 11:12.000] and this is infinite if you get involved with differential equations and, you know, [11:12.000 --> 11:15.000] complicated mathematics, everything moves like crazy. [11:15.000 --> 11:23.000] All those moving arrows can be represented with an independent program on its own. [11:23.000 --> 11:26.000] And those programs interact with each other. [11:26.000 --> 11:30.000] This is the model of the actor that I can imagine that most of you, more or less, [11:30.000 --> 11:33.000] would be familiar with, like, what we do in Erlang and Elixir. [11:33.000 --> 11:42.000] For those of you that are not, the idea, basically, by the way, before I go to the next slide, [11:42.000 --> 11:50.000] this is Karl Hewitt, the guy that named the actor model that put it into paper. [11:50.000 --> 11:55.000] He died a month ago, or almost two, maybe, somewhere in mid-December. [11:55.000 --> 11:57.000] So, a bit of a tribute to him. [11:57.000 --> 11:59.000] Thank you for the theory. [11:59.000 --> 12:03.000] For those of you that may not be familiar with the concept of the actor, [12:03.000 --> 12:06.000] basically, it's the universal primitive. [12:06.000 --> 12:10.000] In a language like Ruby, for example, everything is an object. [12:10.000 --> 12:14.000] You can do whatever, dot something, and maybe it will crash because it's not valid. [12:14.000 --> 12:16.000] The compiler may tell you, but you can. [12:16.000 --> 12:18.000] That's how you design your program. [12:18.000 --> 12:20.000] In a language like Lisp, everything is a function. [12:20.000 --> 12:21.000] Absolutely everything. [12:21.000 --> 12:23.000] You can do whatever parentheses. [12:23.000 --> 12:24.000] And maybe it's not valid. [12:24.000 --> 12:25.000] Maybe it will crash. [12:25.000 --> 12:28.000] Maybe the compiler will tell you before compiling. [12:28.000 --> 12:30.000] In a language like Erlang, everything is an actor. [12:30.000 --> 12:33.000] You can do whatever exclamation marks send a message. [12:33.000 --> 12:35.000] And it's almost never valid. [12:35.000 --> 12:40.000] It's only by a process identifier, or if it has a name, a proper name. [12:40.000 --> 12:44.000] So, this is the model of your program. [12:44.000 --> 12:47.000] This is how you structure the program. [12:47.000 --> 12:57.000] How are we going to load test a service? [12:57.000 --> 13:04.000] Light thickens, and the crawl makes wing to the rocky wood. [13:04.000 --> 13:06.000] This has lots of background. [13:06.000 --> 13:07.000] It's a very personal thing. [13:07.000 --> 13:10.000] First of all, of course, I love Shakespeare, but that's not the point. [13:10.000 --> 13:13.000] I work, as I said, at the beginning in MongoSIM service. [13:13.000 --> 13:15.000] That is an XMPP implementation. [13:15.000 --> 13:19.000] And in XMPP, I don't know why, but I'm very happy about it. [13:19.000 --> 13:26.000] All the examples in the RFC are given with Shakespeare quotes. [13:26.000 --> 13:31.000] So, when it comes to messages, you know, there is Alice writing to, not Alice. [13:31.000 --> 13:36.000] Juliet writing to Romeo from the balcony, and then all the examples are like this. [13:36.000 --> 13:44.000] So, we made a piece of service based on a quote from Shakespeare, the name. [13:44.000 --> 13:48.000] That is called a murder of crows. [13:48.000 --> 13:51.000] I also love Hitchcock. [13:51.000 --> 13:55.000] If you haven't watched it, please watch this movie. [13:55.000 --> 14:03.000] So, there is this library that we created in my team to test MongoSIM on the load. [14:03.000 --> 14:09.000] That is called a murder of crows, because crows are dangerous and are there to kill you and eat your corpse. [14:09.000 --> 14:17.000] So, this is what we try to do, to just kill MongoSIM, see dying, and then try to make it stronger next time. [14:17.000 --> 14:23.000] And with this project, we reflect about the interactions, the traffic capacity, [14:23.000 --> 14:26.000] amplifying factor, all new forces. [14:26.000 --> 14:31.000] So, in the case of a messaging system, there is this vulnerability that happens to everyone back in the day. [14:31.000 --> 14:32.000] You know, there is compression. [14:32.000 --> 14:37.000] Somebody sends you a small packet, you decompress it, and boom, your run out of memory. [14:37.000 --> 14:42.000] These kind of things, you have to look for these amplifying forces, the traffic capacity, [14:42.000 --> 14:52.000] how much traffic each client can send, how many clients can you have, all new forces. [14:52.000 --> 15:00.000] Something that may not be a surprise for old schoolers, Erlang developers. [15:00.000 --> 15:06.000] This new world of cloud, that is someone else's computer, really. [15:06.000 --> 15:11.000] If all your microservices connection are a lot less stable, distribution is not as cool and easy [15:11.000 --> 15:15.000] as it was when Ericsson made it and hardware was indestructible, you know, the punching theory. [15:15.000 --> 15:16.000] Nothing happens. [15:16.000 --> 15:18.000] Now it dies. [15:18.000 --> 15:25.000] So, all new forces that now make a difference in the new way of building a system. [15:25.000 --> 15:31.000] In the case of MongoSIM, we have these usual use cases, session establishment. [15:31.000 --> 15:36.000] So, you know, somebody logs in, authentication, password, password less, make up your mind. [15:36.000 --> 15:37.000] Send messages. [15:37.000 --> 15:39.000] Obviously, it's all about sending messages. [15:39.000 --> 15:41.000] Fetch in your archive. [15:41.000 --> 15:45.000] You reconnect after a while, you are on holidays, and then you fetch all the messages you lost. [15:45.000 --> 15:46.000] This is stored somewhere. [15:46.000 --> 15:48.000] It has to be stored as you send it. [15:48.000 --> 15:52.000] What is the impact that it has on sending, on receiving? [15:52.000 --> 15:55.000] Joining and leaving group chats. [15:55.000 --> 16:03.000] This is something, and in all classic XMPP, it's a problem to scale, but all classic [16:03.000 --> 16:04.000] with the time happened. [16:04.000 --> 16:06.000] We had solutions for that. [16:06.000 --> 16:07.000] So, I had these problems. [16:07.000 --> 16:08.000] We need to test them. [16:08.000 --> 16:12.000] And we think how to test them. [16:12.000 --> 16:19.000] So, you start your scenario, and at testing time, you need a init, a startup. [16:19.000 --> 16:25.000] Like, start the metrics, start the functionality that is going to coordinate all your actors [16:25.000 --> 16:27.000] when they have some interaction between them. [16:27.000 --> 16:31.000] For example, in a group chat, you are going to create so many actors that then they will [16:31.000 --> 16:33.000] join the same group chat and talk to each other. [16:33.000 --> 16:38.000] Or in a multi-user game, you are going to have millions of users, but they will cluster [16:38.000 --> 16:39.000] in groups. [16:39.000 --> 16:40.000] So, you need to coordinate them. [16:40.000 --> 16:46.000] So, you will start logic to capture users and to coordinate them and join the same group, [16:46.000 --> 16:48.000] et cetera, et cetera. [16:48.000 --> 16:50.000] So, you start all the actors. [16:50.000 --> 16:58.000] After all your init, then you spawn all the process, you know, and each one executes the [16:58.000 --> 17:03.000] program they are supposed to, that they have been coded to do. [17:03.000 --> 17:05.000] And then you run it. [17:05.000 --> 17:06.000] Locally or distributed. [17:06.000 --> 17:11.000] At some point, the load that you can generate doesn't fit in a single computer, so it has [17:11.000 --> 17:15.000] to be distributed, so you need your service to handle the distribution for you. [17:15.000 --> 17:23.000] The purpose of the load testing is checking how your software is going to survive or die [17:23.000 --> 17:28.000] and not implementing the load testing idea. [17:28.000 --> 17:35.000] We want a load testing library that will just give me all the users, give me a way to coordinate [17:35.000 --> 17:40.000] them when I have to, to throttle them when I have to, and the rate that I have to, to [17:40.000 --> 17:46.000] handle whatever place I need to start this load testing. [17:46.000 --> 17:48.000] And I don't want to think about all of that. [17:48.000 --> 17:53.000] I just want to describe the scenario that I'm going to use to kill my service. [17:53.000 --> 17:59.000] So, we build a library that does all that other stuff. [17:59.000 --> 18:02.000] Very important thing is the throttle idea. [18:02.000 --> 18:07.000] In the case of the chat service, imagine that a million users connect exactly at the same [18:07.000 --> 18:09.000] time and looking at the same time. [18:09.000 --> 18:11.000] It's probably not a real use case. [18:11.000 --> 18:16.000] You can test for that, but that is the stress part when you want to kill the service. [18:16.000 --> 18:22.000] That later, you would usually see what happens when you connect 100 per second, and then [18:22.000 --> 18:28.000] you increment 200 per second, 500 per second, 1,000 per second, and you want to have a [18:28.000 --> 18:33.000] functionality that will throttle and progressively increment the rate. [18:33.000 --> 18:39.000] And then seeing your metrics, both load testing library will output to Grafana, your service [18:39.000 --> 18:44.000] that you're testing will output to Grafana, and then see the correlations. [18:44.000 --> 18:49.000] You want actors to wait for the permission. [18:49.000 --> 18:51.000] Am I allowed to do this already? [18:51.000 --> 18:56.000] And the cases, the session establishment, but also joining a group chat, how many messages [18:56.000 --> 18:58.000] are you going to send. [18:58.000 --> 19:02.000] There is this, you know, you have an arrow that is going to be applied in one place. [19:02.000 --> 19:04.000] How big do you want the arrow to be? [19:04.000 --> 19:09.000] You want that arrow to grow incrementally. [19:09.000 --> 19:13.000] And you may want to ask another actor to wait for the approval. [19:13.000 --> 19:20.000] You can tell the throttle logic to tell that actor to wait for something. [19:20.000 --> 19:25.000] And then that actor, which is not yourself, will wait for the action. [19:25.000 --> 19:28.000] For example, in the case of joining a group chat, first you have to create it. [19:28.000 --> 19:33.000] So there is a first user that says to everyone, wait, don't join because I need to create the group chat first. [19:33.000 --> 19:38.000] Voila is created, come here, et cetera. [19:38.000 --> 19:43.000] And another very piece of important functionality is the coordination idea. [19:43.000 --> 19:52.000] So as actors are appearing in your load test, one thing that you will want to do, as I said before, [19:52.000 --> 19:54.000] is to coordinate sets of them. [19:54.000 --> 19:57.000] For example, who is going to write to whom? [19:57.000 --> 20:03.000] So you want an actor to know about another one, so it can send him a message. [20:03.000 --> 20:11.000] You want a functionality that will pick up actors as they are starting in a configurable way, [20:11.000 --> 20:18.000] either all of them that are started or sets of pairs or a list of them. [20:18.000 --> 20:25.000] And once the configurable amount of actors has started, then make them do something. [20:25.000 --> 20:33.000] There is a callback that will get the list of actors that they identify as and will coordinate how they interact with each other. [20:33.000 --> 20:43.000] And, yeah, the actor, as they join the coordinator, they will be given the function that they have to do. [20:43.000 --> 20:53.000] So to us, this is what my load testing framework is supposed to help me do. [20:53.000 --> 20:55.000] We use it for XMPP. [20:55.000 --> 21:02.000] So then we have scenarios and functionality written that knows how to do the authentication for the protocol, [21:02.000 --> 21:04.000] that knows the functionality of Mongoose IM. [21:04.000 --> 21:13.000] But we don't believe that the load testing library is the one that decides your scenario. [21:13.000 --> 21:20.000] I have seen different load testing frameworks that give you functionality to run HTTP requests. [21:20.000 --> 21:24.000] So what if you are not testing something HTTP related? [21:24.000 --> 21:30.000] We believe that the best way to write what you want to test is to write the code that you know how to write anyway. [21:30.000 --> 21:35.000] So the idea is that you write Erlang, Elixir is on the way. [21:35.000 --> 21:41.000] This library is not integrated with Elixir, but we will pull requests accepted. [21:41.000 --> 21:51.000] The library, as I say, is called AMOC, an acronym for an order of crowds because you want to see your service dying. [21:51.000 --> 21:53.000] There is the repo, you can look it up. [21:53.000 --> 22:03.000] We have this other repo that we call AMOC Arsenal where we have all the scenarios for XMPP where you can take inspiration on how they work. [22:03.000 --> 22:12.000] And I'm about to finish here. I propose to myself that I would make this presentation without showing a single line of code. [22:12.000 --> 22:17.000] So I actually cutted the screenshot before the code starts. [22:17.000 --> 22:19.000] Let's see how it works. [22:19.000 --> 22:24.000] In previous presentation I have shown a lot and it's a bit more complicated to explain. [22:24.000 --> 22:33.000] So the library has documentation. Another thing that I have pending is to use the new XDOP documentation. [22:33.000 --> 22:38.000] It doesn't have it yet, but it has a beautiful markdown that you can read in GitHub pages. [22:38.000 --> 22:43.000] And the scenarios library for inspiration. [22:43.000 --> 22:45.000] That is all I will have for you. [22:45.000 --> 22:46.000] This is my handle. [22:46.000 --> 22:51.000] That is to repos links for MongoSIM and for AMOC. [22:51.000 --> 22:56.000] And this is a picture that I have everywhere if you see some Nelson videos and you don't know if it's me. [22:56.000 --> 22:59.000] It's going to be that one if it has that picture. [22:59.000 --> 23:01.000] That's all from me. Thank you very much. [23:01.000 --> 23:08.000] Thank you, Nelson. [23:08.000 --> 23:11.000] So is there any questions? [23:11.000 --> 23:14.000] Yeah. [23:14.000 --> 23:16.000] I know that there's also a library called Zang. [23:16.000 --> 23:21.000] It's a low testing library written in early. So how is this one different? [23:21.000 --> 23:24.000] In that one you write the scenario in XML. [23:24.000 --> 23:28.000] And it has a, how do you call it? [23:28.000 --> 23:33.000] Like a domain specific language, XML base to describe what you want to do. [23:33.000 --> 23:37.000] And the library has to offer you the protocol. [23:37.000 --> 23:42.000] So that library actually has HTTP and XMPP helper functionality. [23:42.000 --> 23:46.000] But if you want a different protocol, the library doesn't give it. [23:46.000 --> 23:49.000] So we thought that we just want to write the airline code. [23:49.000 --> 23:54.000] It's way more pleasant to write and also less limited. [23:54.000 --> 23:58.000] Okay, thank you. [23:58.000 --> 24:02.000] Other questions? [24:02.000 --> 24:14.000] So by using the murder of Kraus, did you already find any like bugs in Mongoose I am that you've been able to fix based on the... [24:14.000 --> 24:17.000] Every single time. [24:17.000 --> 24:20.000] Fair. [24:20.000 --> 24:25.000] Useful bottlenecks sometimes are database interactions. [24:25.000 --> 24:28.000] And all fours that didn't used to matter in the computer you could punch. [24:28.000 --> 24:34.000] But now, so as you write messages, you need to make sure that they are recoverable. [24:34.000 --> 24:45.000] But the amount of messages that you can send might not be as scalable as the amount of inserts a database can have. [24:45.000 --> 24:48.000] So this is something that we test a lot. [24:48.000 --> 24:54.000] And another functionality that we do is the time to delivery. [24:54.000 --> 24:58.000] So the sender puts a timestamp and the receiver just measures the difference. [24:58.000 --> 25:08.000] And that's something that we also test continuously when we change something to see that we didn't introduce a computation that would make the time to delivery longer. [25:08.000 --> 25:14.000] So those are the two most common tests that we test almost all the time and then there are each case that we don't test as regularly. [25:14.000 --> 25:20.000] But we have all the scenarios for them. [25:20.000 --> 25:23.000] Any other question? [25:23.000 --> 25:29.000] I wanted to mention another library I saw that is called MZBench, I think. [25:29.000 --> 25:31.000] I don't know that one. [25:31.000 --> 25:38.000] Yeah, I think it was... I know it because it was used by VernMQ to do its load testing, I think. [25:38.000 --> 25:42.000] And I think it's in Erlang, too, and you write scenarios. [25:42.000 --> 25:55.000] But is Emoq able to... If I have an actor that has to perform some action and then pass the state to another actor, is that possible? [25:55.000 --> 25:59.000] Or is that... You have to write your own code, basically, to do that. [25:59.000 --> 26:01.000] I have. The coordinator would help. [26:01.000 --> 26:02.000] Okay. [26:02.000 --> 26:06.000] So in the coordinator you can say to pick up pairs of actors and then they say... [26:06.000 --> 26:07.000] Okay, you had the first one. [26:07.000 --> 26:08.000] Okay. [26:08.000 --> 26:09.000] Yeah. [26:09.000 --> 26:11.000] Any other question? [26:11.000 --> 26:18.000] We have something similar for changing the owner of a room and then actors have to pass the state, the knowledge to another one. [26:18.000 --> 26:22.000] Okay. [26:22.000 --> 26:24.000] Okay, thank you again. [26:24.000 --> 26:42.000] We'll see if there are any other questions.