 Move the shit out of the way. Good. Who is this? I think it's Max. Mine. Oh, God. There you go. And I was about to throw it at the table. All right. So I'm going to talk about, is this too loud? Maybe it's too loud. Is this too loud? Good. Generally, yes. But after Max talks, just put it up here. Oh, shit. Okay. So I'm going to talk about the answer to, and give you an official status update. And hopefully we'll have performance left at the end, and we'll give you a really cool, fast introduction to a new feature that I just included yesterday. So, if you've used the answer, how many people here use the answer, or know about the answer? That's great. How many people here know about the answer to? Just a quick survey. All right. How many people use it? I especially like the... Okay. So, talk a bit about the answer. First of all, the answer really is, it's awesome. It's fantastic. It's great. It really, really, really is. It is very fun to use. It is very fun to share. We want to show things, right? It is what I would like to call pro-fully beautiful, which means that it's a really nice showcase of how you can have beautiful, pearl code, okay? And really nice technology and really nice abilities for our applications. And it is a very good way to attract newbies. We get, oftentimes, we get people who join the dancer channel and talk to us about writing a new piece of software and they go, like, well, yeah, I don't actually know pearl, but I saw this thing and it looks really nice. I would like to learn pearl just enough to give you an insight into the answer. And this is a very, very important point to know. When we have really nice technology, people pick up on that. And job-wise, marketing-wise, it's very successful. There are now a few job descriptions that actually include, hey, if you know the answer, this is useful for you in our job. And as I just explained, it is a very good showcase of what modern pearl is and what modern pearl should be. So overall, not bad. Of course, the community is awesome. The community is fantastic. We have a very lively, a very warm, happy, kind community. It's fantastic. Sorry? So they come in. So until you join. So we have a, don't troll, so we have a very happy community. Overall, it's also very successful. 850 stars, which used to be watchers, on GitHub with over 300 forks, over 1600 issues. It's insane. And just talking about GitHub, that does not include RT, mailing lists, emails, IRC. We take bug reports and feature requests from every possible channel. Okay? So if you email one of us, or if you email to the list with something, we'll create a ticket. Or we'll work with you to create the ticket. Sorry, kid, you're in on. So that also does include stuff that the community created, like plugins. Hey, we do some conference talks, not just me, pro-members, and articles. So overall, it's just very, very successful. It's very warm. It's very fluffy and fun to work with. And of course that means we're also getting very famous. We have some newspaper articles, and magazines, and blogs, and news websites. And there's a few companies that use Dancer, like, hey, Booking, and Shutterstock, and Novel, and UK2. UK2 is an ISP. Novel has an entire product that is based on Dancer. Shutterstock has some search stuff, and Booking has various utilities, also written in Dancer. There's some government websites that are written in Dancer. There's some personal blogs. There are wikis. There are actual libraries that are written in Dancer. It's really, really nice to see. It's very exciting. And we participated in Google Summer of Code. How many people here know Google Summer of Code? Fantastic to know what it is. How many people here know the outreach program for women? So it's a very similar program that tries to influence, to get some companies not born to influence, but to get some companies to sponsor women to go into open source. It's fantastic. So we also participate in that. So all of this kind of leads to this thing. Why Dancer, too? If everything is great, what is the problem? And one point, where is Dancer, too? Which is a question that we get asked quite often. So we talk about Dancers who actually want to start with something else. Suppose a car worker says, Hey, you know what? I think I'll just use Globals to solve this problem here. Can anyone imagine your response? Mine is this. Right? Because they're horrible. They're really, really bad. Globals are singletons, which basically means we get one instance and we only get one instance and every other attempt to work goes to that instance. So it's one shared information between all the other consumers. And Dancer one requests responses, serializers, hooks, they're all global. They're all singletons. This means that the serializers, for example, if you have a serializer, these serializers request to come in in JSON format and provide you with just object that you can work with or structure that you can work with. And when you're done with that and you throw a structure out, it serializes automatically in JSON back. All of your Dancer applications in that process will do that for you. All of them. You cannot change this. And your hooks, they're global. This becomes a problem. And it's important to know because people will be like, why did you do this? We did it. What we actually did was take an existing framework called Sinatra written in Ruby. The founder of Dancer is also a real programmer. He really liked Sinatra. It's very nice. And he said, well, wouldn't it be nice to have this thing in Pro 2? And he provided it. And this is the design of Sinatra. So we're kind of stuck with this. And when people came in to Dancer and they went, you know what? I'm thinking we're going to use this for like, serious stuff. All of you, this is great. And then they realized, oh, wait, this is a problem here. We cannot have single-sins everywhere. This means that you cannot also run multiple apps in a single process. And there wasn't available fix pretty early. But we didn't want it. So we didn't merge it. We wanted it to be done right. And the fix was kind of like a workaround. So what did we do? We started the answer 2. So the answer 2 is the rewrite of the code. It has no locals. Well, there is one, but that's just the runner. You always have just one. There's a DSL mental layer. It's a completely separate layer. Which means that we can hack on the internals as much as we want. And your code, which is the DSL, stays exactly the same. Which is fantastic. So I can break shit as much as I want. You won't ever see it. It's really, really good for developers. We have clean internals as much as we can. We're working on cleaning them even more. And we're using MOO, which is a very good object system. So we don't have to reinvent that thing. So overall, hell yeah. So what is the answer to it in a few other words? First of all, it's more compartmentalized. Which means that everything is more separated. So each app is its own thing. It has its own context. It has its own scope. It's more compartmentalized. So when you create apps, you can actually use them in different places. It's fantastic. And it's worth a couple. Same direction. Also, the answer to is more dependencies relaxed. This means that we don't actually care about dependencies. I know some people do. But what we did was actually ask our users. Well, what if we keep the dependencies down to, say, maybe four or five dependencies? Or fewer. Or maybe six. And they're like, we don't give a shit. We don't care about dependencies. If we're at the point that we can use the answer, we can use dependencies. When you take a look at second liners in Carton, in Fat Packer, in Pinto, dependencies are not a problem anymore. Just knowing that you can use these. There's local live not on the list here, but some of it uses it. It's really, it's no longer an issue. Another interesting point is that the answer to by default and by policy is what we call Fat Packable. And that means that you can always pack your entire application, including all of the code of the answer to into a single file. That's it. You can send that file. It's everything in it, bundled. So no dependency problems. So we're much more relaxed. We're much more oriented towards cooperation with other frameworks. That means that if there is a commonality, and in some cases there are, with catalyst or with simple, but any other web framework that wants to join in on this attempt, we actually try to find a comfortable way that suits all of us. One interesting example is route definitions, or root definitions, where you have a path, and you have a main language to define that path, like colon for variable name or question mark for optional. And web simple also has a root definition. And we wondered, could we join these and merge them into what root definition that both systems could use? We can, and we probably will. Another interesting point is that we really try to push more things into middlewares so they can be shared across systems and across frameworks. So again, going towards cooperation, rather than building our own niche that no one else can play with. And lastly, dancing through is an opportunity to get it done right. To get it done on an architecture level, to get it done on a programming level, to get it done as like a really good pro-program in IK. An interesting example is this guy. This is Gene. Gene is from Luxembourg, Lebanon, and Germany. And when I went to the German pro workshop just now, he came up and he was like, hey, I would like to contribute. What do I do? And we found an issue right away in POR that we needed some help with. It was a small feature that we wanted. It could be maybe a feature or a bug or missing implementation. And he grogged the entire code base as much as he needed and finished the feature off on his own in under two hours. He came up a bit later, hey, I'm done. I pushed it. Could you look at it? Holy shit. So it is an opportunity for all of us to get into programming as well. So what is the development process of Dancer 2? It currently looks like this. There's a lot of reflecting, a lot of anguish. There's berserker releases in which I get absolutely insane batching crazy and just, ah, release. Not very good. And what it should look like is this. Time box release cycles. Something like every two weeks, which we're definitely moving up to. A policy document that defines what our policy is regarding several different concepts. It exists. We need to revise and release it. We need to have coordinators. So someone coordinating documentation. So if you want to contribute to the documentation, you just go to the coordinator and he says, okay, here's something we need help with. Oh, you just contributed something. Let me merge it and give you the feedback on that. And we need some compatibility shins. We need to make sure that we're breaking as few things as possible. Which leads us to how do we actually fix this? How do we actually reach that point? So we have a problem of not enough time. But we're improving on this. One of the biggest things is to make Dancer a business priority. And although we don't like the idea of corporates, but once this becomes something that companies actually use, that means that we can actually put company time on it and company money on it. And that is very, very important. Revision to policy document. We need to get the coordinators to coordinate. We have coordinators, but they have too many tasks. They didn't actually get to coordinate anything. Which means that everyone can be a coordinate. So if you're actually thinking, hey, I can actually coordinate some documentation patches, I don't mind. Please, join us. We want to have more core devs. We recently added Russell Jenkins, Stephen Humphrey, and our very own Miki Naseati, who gave the talk about medicine for client. These are fresh, fresh flood into the core devs list, which is the TASA. And we need to make a shit list or a hit list, depends, which are like our important things. The things that we want to change and tackle on, they're still not the way we want it to be. So what I would tackle myself, this is my personal hit list. I want to have full support for raw PSGI subsidies. Work on the way, actually, this is not working. And you know what this means? This means that Dancer is now completely asynchronous. It's really nice. I'm going to show a recorded console session. We need to improve our path detection. We want to revise the whole system, get some more interoperability with plugins. There's some internal cleanup that we want to do. What is the coupling of the configuration rules? Done. We had a hackathon yesterday. Another one is removing the answer to test, or at least the usage of the answer to test. Done. I did this during the German pro workshop, because all the talks were in German, so I had a lot of time to hack. And the server role that was conflated with the runner role, and that's it. It's done. It's cleaned right off at the hackathon yesterday as well. I want to improve the session handling a bit. And honestly, this is the lesson most of this is done, so I'm really, really excited. So, where do we go now? Corporate attention leads to development and maintenance time. Sponsorship and donations lead to hackathons, like the one we had yesterday. And workshops also lead to hackathons, which is under collaboration. Also provide user visibility and feedback. So, this is your time to shine as users. And please, grab me later. We can have a chat about it. Now, this is this part of the talk. How much time do I have left? I don't even know what time it is. Two or three minutes. All right. So in these two or three minutes, I'm going to show a four-minute presentation. There you go. No. This one. Okay. So it's started. What I have here is a screen with four panes. Okay. And I'm going to show this dancer app. It's a package named event-based app. And it will use dancer 2 just to get a syntax. Okay. I'm going to use any event to have some event-based routines. We're going to use time high res to get accurate time and high resolution. There's an array here to keep all the timers that we're going to create with any event. These timers are going to run things that take longer on polling. There's a root here called slash ping. And that will just return the date of time. Now, we're going to have a longer-running request. It's going to be in slash long. And I'm just going to show what we're going to do here. It's going to return a subroutine. And that's going to get a responder, which is a code reference. This is a pure plaque, a pure PSGI response. And responder, there's no dancer stuff going in here. It's just facilitated by dancer. We created a timer using any event into the timers array. It will run after five seconds interval zero, which means it will only run once. And it's going to run this callback. After five seconds, it's going to call the responder code ref and send it a pure PSGI response that just says 200 OK, no headers, and the content high. So there's a timer here. And when you go too long, it does in just five seconds and then sends high. And then we shift the timers just to throw out the object we created. And at the end, I have get slash sleep with just leaves five seconds. So I want to show the difference between non-blocking sleep, which is the timer, and blocking sleep, which is the actual sleep call. And at the end, we have dance, which just returns a code reference, a PSGI code reference. So let's see what I did here. The first thing would be to run this. And I'm going to use Twiggy. I'm starting with plaque up over there. Takes lib, which is the dancer that I haven't committed yet. And we're calling Twiggy, which is actually an any event-based web server. And I'm giving it the event-based app. So it just started. It's accepting connections. And we can play with this. Then we can go to a different pane over there. And what I'm going to run here is that while true forever, do a request using curl to 1.7.001.500 slash pane, which means go here and get a pump back and sleep 0.4 seconds all the time forever. Here it is. These are the requests coming into the server. These are the responses that we get from the server with the time. And now what we're going to do, you can see it just, the more I push it, it's live. It's running. Now, what I'm going to do is call long for a longer new request. Okay? Here we go. It's going to take five seconds. Then it's going to return. But notice that this is running at the same time. It took five seconds. I'm going to run it again. It took five seconds. You can see that it's still running all the time. Right? We didn't actually stop the web server from giving other request responses. Now, this is sleep. And when I run sleep, you know, it just, it hangs. That's it. Until sleep is over. This space means I haven't done anything. And here you can see that when they get to slap sleep, the output for the log was only generated after it finished sleeping. It couldn't even output to the log until it was done. So calling log, actually long, actually less than running. And I'm running multiple panes now at the same time. So long here, long here. And you can see that it's still running. Everything is still running, even though the screen looks a bit shitty. And this is the interesting part, that we were able to return a response saying, here's a response but still allow other stuff to go on at the same time. This is async. A lot of people asked about the answer to this. This took me about four lines of patch. That's it. I did it last night. Very simple. So this is answer two. I think we're going into a very good direction. And if you're interested in that, grab your later. And that's it. Thank you very much.