What is going on everyone? Welcome back to my channel. My name is Jocelyn Jay. For those of you all who are new here Welcome glad to have you here. So if you decided to click on this video It's either because you have an iPad Pro and you're interested in doing Programming with it or you're in the market for an iPad Pro and they're pretty expensive You need something to convince you that it's worth the price or you really like thumbnail Either way, I'm glad to have you here thoroughly enjoy using the iPad Pro and not just for watching YouTube videos or Netflix Consuming content, but using it as a replacement for my laptop for lightweight tasks like writing emails Responding to text messages writing notes and photo editing, but here's the thing We know that the iPad Pro can replace your laptop But one interesting capability that this device has to offer is its web development capabilities To be honest with you. I didn't buy this 2020 iPad Pro 11 inch to do programming I really just bought it as an extra device to not only consume media But to also do some content creation some workflow stuff and to use it for notes However, there are some great applications out there that allow you to do web development that range in pricing from free To around $30. I really wouldn't pay more if there are apps that cost more than that But these applications give you the ability to do web development and they have integration with github Okay, so now that we talked about the iPad Pro Let's take a quick dive into no GS before I show you how to build a simple application with play JS There's been a constant increase in enterprises adopting this model of Responsive web development to optimize the experience and the accessibility Along with the performance of a web application Nowadays, it's essential for a web developer to be proficient in CSS HTML and JavaScript Sometimes you have developers that feel really proficient in one or the other like CSS slash HTML But not really JavaScript or vice versa those back in no JS Developers main point of this video really is to show you how you can create a web application with no JS No JS is a server-side JavaScript language and traditionally JavaScript has been executed through a web browser such as Google Chrome Safari and Firefox so when comparing client JavaScript versus no JS line JavaScript Which is the more traditional way of executing JavaScript it executes JavaScript through the browser whereas no JS executes JavaScript through the computer I want to take a moment to talk about uJS Briefly since we're going to be building our project off of a no JS slash view JS template uJS is a Progressive JavaScript framework for building modern user interfaces the core component or library is primarily focused on The view so instead of having three files a CSS file HTML file in a JavaScript file You'll have a script tag a style tag and you'll have a template tag where you'll have all your HTML in One view component this may not make a ton of sense right now But I promise it'll make perfect sense in a few moments uJS is very small and lightweight It's pretty easy to pick up I like the fact that you have one file that hosts all of your web Development so you have your four lifecycle hooks inside your script tag You have your styling and your style tag and you have your HTML in the template tag So it's pretty easy to pick up especially if you have Understanding of JavaScript HTML and CSS other powerful capabilities that uJS offer is it's capable single page application usage along with being able to build Components register components and build reusable components So the first thing you want to do is go to the app store and install Play.js it does cost $5, but it's worth every penny in my opinion After you've installed the application you want to click the plus button and enter a project name and Then under the type section click the drop-down and select no.js plus view.js template then click create So you're going to see an index.js file But we can ignore that and what you need to do now is open your app.view file and hello world View file you can find these files by selecting the files icon at the top of the left navigation bar Then select component and you'll see the hello world view file So now that we have that open select the files icon again Then select the folder with the two dots This will move you up a level in the directory where the app.view file is you create a view.js project It always comes packaged with with starter code to get you started and to give you a basic understanding of how the source Code is organized and how the framework works now select the play button in the bottom left Which is where the debug window is that I'll tell you the status of your app So if you have any errors, it'll let you know in that window select resolve modules This will take a few moments Once the modules are resolved you can expand the debug window and see that your app compiled successfully Okay, now my favorite part viewing your view.js application Select the globe in the bottom right of the app within the same debug window This will serve your app to the browser. You should see a welcome to your view.js app Congratulations, you served your first view.js app on the iPad Pro. Okay, so now that we got that done We're gonna be doing a little bit of coding so you can get comfortable with view.js and the app play.js Along with some basic web development for the sake of not making this video Incredibly long. I'm gonna be fast forwarding through most of the code But I promise all the really important things I'll be sure to talk about the main purpose of this video is for you to get started with view.js and the play.js Application that way you can work on web development using modern JavaScript frameworks Okay, so the first thing you'll notice is the view.js logo and some hyper hyperlinks underneath the logo Everything but the logo is actually created in another component, which is the hello world component Remember when I talked about being able to pass a component to other components This is an example of that so in the hello world component You see there's some HTML a script tag and a style tag and the first thing we want to do is rename this component to header So the first thing we're going to do is go back to the app.view file and change them import name from hello world to header Along with the component name View.js is going to throw an error. Don't worry It's because we haven't changed the name of the hello world file to header now change the tag name in the template HTML in the app.view file from hello world to header That's all we have to do within the app.view file go back to the hello world file and change the name to header This is the component will be spending 90% of our time writing the code Also, make sure to change the name of the header component in the script section from hello world to header This is important because this will be the name of the tag We call in the app.view file once that is done delete everything within the template besides the highest level div class Hello, and the H1 with the message property inside the curly braces now Go back to the app.view file and delete the image. You should see the welcome to your view js app H1 okay, now the fun part like I mentioned I'm going to fast forward through most of this and If you're interested in learning more about JavaScript frameworks like view angular react along with more Web development stuff with CSS and HTML or technologies not stuff Be sure to give this video a thumbs up and comment down below Code with me that will help me greatly in terms of knowing what type of videos to make and it helps with the YouTube algorithm Oh and one more thing if your app performs poorly probably just need to like restart it I know mine was but maybe that's because I was like uploading a YouTube video along with recording the screen But if you notice that Your app is being slow and maybe the local host isn't working isn't showing your app Then I would recommend rebooting it now. We're gonna just be focusing on CSS and HTML All right, we got a sweet-looking plant app. We use some display flex with CSS We created a property and we passed that property to a component Hope you all enjoyed this video Give it a thumbs up if you enjoyed it at all or if you're still here comment down below some of your favorite Technologies that allow you to do development on the iPad Pro subscribe to the channel if you haven't already I love you all to become a part of this community and as always have a blessed rest of your week I'll see you all soon. Peace


We have gathered here to discuss the Memoids of Prabir Prakast and we have a panel of imminent journalist, writers, advocate. We'll be speaking about the book and the subject. I just want to say one thing about Prabir. Right now, Prabir has been in the news for reasons that you all know. But what's really important about the book and what moved me personally the most is the fact that here's a man who I have personally known as a friend, as a comrade, as a mentor, as a leader for many years. But there's a way in which even if you know the person very well, you don't get a sense of the entirety of their life and their life's work. And that's really what this book does because what it tells you is that here's a person who has been in every way, everything that a good citizen of this country should be. He has been an outstanding citizen of this country and he has been a patriot who has fought for the sovereignty of the country on issues of patents on telecom and so on and so forth, on the nuclear deal and so on. All of this you'll get a sense of when you read the book. He's also one of the very few people who has the distinction of having been imprisoned by two authoritarian regimes 50 years apart. And for somebody like me who's much younger than him, but who's always looked up to Prabir as I said, as a friend, but also as a leader, as a comrade, this really is truly inspiring that here's a man who at this stage in his life is in, they can imprison his body, but they cannot imprison his mind. And they cannot put a lock on people who will speak up in this country. That's what this book is all about, keeping up the good fight. I read the book with great interest. It's a very simply narrated. It's a simple story at the surface, very straightforward, accessible, but actually very nuanced and full of insights and surprises in the stories that it tells. And the most interesting thing, of course, is the connection it draws between the emergency of 1975, 77, and in particular, Prabir's role in it, that he was picked up, mistaken for somebody else. And then although they brought that mistake to light, repeatedly it was said that the matter involved the Prime Minister's house, which was codeword for Sanjay Gandhi and his group at that time. And so they kept him in for one year. And I think the story of Prabir's imprisonment under the Maintenance of Internal Security Act, or MISA, for no conceivable reason is fascinating. Full of humor, he learned many lessons from it and that has to be read. And then connecting it to what has happened to the present, much more serious attack in perhaps darker times, whether it's a command of undeclared emergency and not is not the issue here, but institutions have been captured, institutions have been manipulated, and media freedom is under full scale attack. Of course, there are still spaces where people speak up and Prabir's book brings that out very clearly. But it's a very disturbing period that this year and I would only refer to it as the Hindutva authoritarian regime. We can talk about specifics or some of the highlights of what journalists and media organizations are being through, but that perhaps can be done later. But I think the most important thing here in this book for me anyway, is that Prabir, talking about the 1970s emergency, says that demolish it or takes issue with the conventional wisdom, which is that people at that time supported the emergency. They then went through the two and a half years, and then they voted in Duragandiyal because they didn't like it. And Prabir takes issue with this saying that this is to underestimate or misread the character of the Indian people, their attitudes, their responses. They wait and watched. But 1977, he says, gave them confidence. They are not passive. They are very observant. And in 1977, the conference that they had made them return Indira Gandhi to Pahar in 1980. A very interesting take on what happened. And I think the lesson for today is things may look bad for media freedom and for the rights of people, fundamental rights, basic human rights, rights guaranteed in our constitution. But don't be pessimistic about it. Well, I did not know Prabir very well. I have met him on an occasion. It was a social occasion. And he came across the quiet, polite man who seemed to be firm in whatever he thought and believed it. I was saying that we as a nation tend to value our liberties so cheaply. And possibly one reason that we value our liberties so cheaply is that we have people like Prabir. We have in this generation, we have people like Umar Khalid. We have the Kabir Kala Manch. We have so many people who in Justice Krishna years, picture squads are martyrs of the constitution. And that's the only way I see them. That we have a written constitution. We have institutions that are supposed to administer the constitution. But when those institutions fail, it is these men and women of conscience who fight the good fight who remind us that the constitution is a solemn compact between citizen and citizen, that this is the nation that we will work together and we will live together. It's unfortunate that Prabir has been a victim of defending the constitution twice in his lifetime. But to end with Prabir's own take on why he's not a victim. He says victimhood drops us of participation in the creation of history. It reduces us to mere objects of history. Instead, I would like to assume the vantage point of the people as makers of history. Yes, the government of the day wields powers that seem to overwhelm individuals and organizations. But it is people and their actions that finally determine history. Not as we please and when we please, but in ways that neither the people nor their rulers anticipate. They say, come at the hour, come at the man. Sometimes wittingly, unwittingly, knowingly, unknowingly, people are chosen to represent the temper of their times. I hope that Prabir is out. I hope that we do not put, that this republic does not put too high a burden on him. His incarceration is for no other reason than the malice and desire to suppress. And that through individual, intellectually, politically, physically, in order to suppress the people and the nation at large and for as a means to power and self-clarification. I just want to say at a personal level that I read this book and I'm missing him. I'm missing him because I'm missing the fact I wanted to say it to him. There is so much, Sudangwa said, I have known him for 50 years. We have had intense engagements together. We have had discussions. We have talked about personal things we know. And yet there is so much more in this book that I did not know. I did not know. And it has been written in a way that has meaning for anybody who picks it up. The first emergency. I want to say that first emergency, second emergency. I don't want to say that that is an undeclared, declared, there's nothing different. Whatever it is, that wasn't a after soon after that, there was the people they started against that. It was just 10 months. It was a silence and the people were hiding. Then everybody came together and started organizing against the authoritarian, the government. But now, after so many years also, there is no such effort is not happening. This authoritarian state is not even allowing that kind of a voices to coming together. And they want to say openly that the opposition should be Mukt Bharat. Opposition Mukt Bharat in democracy, no prime minister or any person cannot say that there should not be opposition. Opposition is any importance in the democracy. So the person who is saying there is no opposition is required and we have to opposition Mukt Bharat Banana Kehra Hai Matlab. It is very clear that no democracy is required. It is an open statement that cannot be done in any democracy. We must join hands and say very clearly. In the democracy, there are 435,000 citizens are under trials without anything in this country. What is this democracy we are talking about? It is not talking about the prabiris in there in the jail. We are talking about the citizens how they are all in the jail without any reason. Why I have taken to the jail? I don't know. Some day you will declare is this is the democracy we are all accepting. These are the larger questions we are now bringing. And that is the reason this book release is not just release. It is releasing our regenerating our energy to fight against any authoritarian state. The author of the evening, the citizen of the evening, the engaged citizen of the evening, the fighter of the evening is here with us and yet not with us. So this anomaly is a sad sign of our times. Prabir speaks a great deal in his book about the ways in which people's rights are curtailed, weakened, even taken away in both times past and present. But I want to say that that is not a complete story. This is something Prabir was very eager to point out when he spoke to us. What kept him doing day after day and in the course in the book is to say that the book, as our lives, is not just bad news. It's not just about dark times. The sort of hope, the sort of political commitment, the belief in the good fight and in fighting the good fight that animates the book is very much here with us in this room. And I do want to underline that point because that mix of both the awareness of dark times as well as our belief that it is for us to do something about it is very much here. So I say this because even though it's a memoir and probably the individual person is there, he's always placed in a larger context in a collective, a collective that can grow into a movement and align with other movements and push for change that will mean better lives for many people. I do want to read one line, which is the story of our recent past and one that continues to unfold is not just about repression. The story is incomplete without the resistance we have witnessed, written about and been part of. And I think this is what keeps us going. And let me also say we keep talking about the good fight. As Ashok would say, we writers like to pick on words and say what is the good fight that we are sort of glibly referring to? I think that the good fight, dissent, the political test, all this that we're talking about for many of us here, it is whether there be a writers or readers or journalists, students, teachers, it is simply the freedom, the right to continue doing our jobs. And we are in a time when law fair, intimidation, draconian laws are stopping us from doing our work. There was one moment where he describes the day the emergency, sorry, the day the election results have come out in 77. And it becomes slowly clear in Delhi that Mrs. Gandhi is losing the election by landslide. He says that he was down with fever that day and could not be out. And he describes how outside the offices of the press, outside Indian Express, outside the Times of India, there was celebrations ongoing. That's a scene that seems extremely difficult to reconcile in today's time, especially with another general election on our head. I think 77 marked a very good period, a good point of departure for the media. I think on the whole, the media did not perform the press that has printed newspapers at that time, more or less, that is the whole media, did not perform well during the emergency. Prabir is a little kind about it, but I think I remember very well. And Mr. Advani's famous statement that you crawl when you're asked to bend, I think is absolutely on the mark. But after that was a very good run for the media for a long time. I think between the late 70s and 1970s, or perhaps nearly 20 years, there was independent journalism, there were lots of spaces, there was coverage of people's movements in quite a few sections of the press. And journalism seemed to flower. And I used to say in those days, whenever I was asked about the media, that India is in an enviable position, certainly in the developing world, when it comes to press freedom. But of course, if you said anything like that today, you'll be accused of pervading fake news. I think it is shameful that large sections of the media have been sub-bond. Of course, they have come under attack, if you can understand why some of them are afraid. Journalists have been murdered. We have the data on that from the Committee to Protect Journalists. We have data on how many journalists have been charged under the UAPA. The wire story brought that out. We know that India is in a unique position, the global impunity index, where journalists are murdered in connection with their work. And nothing seems to, no justice is rendered. And we are a founding and permanent member of that Club of Shame that is documented year after year by the Committee, CPJ, the Committee to Protect Journalists. But this is what I agree with Praveer. And of course, the book largely leads out what the latest attack on news click. But I was very encouraged by the solidarity campaign that was spoken about earlier by the President of the Press Club of India and others. I think it's surprising for all of us that so many organizations, Press Clubs, the Editors Guild of India, the other organizations, the Network of Women in Media India, Digipam, of course, also the Committee to Protect Journalists and others, came out in solidarity. And we know that the whole McCarthyite campaign, I think it's not essentially a media story. It's about a completely new socio-political formation, ideological formation, which has injected a lot of poison into the information ecosystem. They all descended on this. And I think this aspect has been missed in some of the analysis. The McCarthyism that descended on news click and Praveer, Praveer in particular, aided and abetted sparked, in fact, a lousy piece of journalism by the New York Times. We have to call them out on this. And the New York Times story, I read it very closely, refers to mixed two casual references to news click, that once it was raided, but they found no evidence that it had some connections with the Chinese. And secondly, that it put out Chinese talking points, whatever that means, as though that were an offense. And it's completely untrue as well. No connection was shown to any funding by a foreign government or any agency other than those which were declared before the authorities, including the Reserve Bank of India. The courts initially gave them decent protection. Then the judge was changed, and the ED went to the court and said it had fresh material. And if you read the FIR, they tried to keep secret, but thanks to resourceful journalists, it came out.  There are good policemen, good police officers, but this was an extremely muddled piece of writing. You can see what it is. A dystopian, you can imagine a dystopian police state. And unless people like our distinguished friend, Mr. Hegde, score in the courts, I am disappointed that the higher judiciary has taken its own time in looking into this matter seriously, and no relief has been provided. But here is a man who's not bitter, because he's fighting the good fight, and he's optimistic. He has confidence in the people and in the legal system. This is a story that is not in the book, but that's a story that I think tells us in the face today. And I compliment the press club of India and everyone here present in this meeting for expressing solidarity, which has encouraged me. So why is the news click? See, we are doing the small movement life. But in India, there are so many newspapers, so many channels, none of them covered even a single day. There is the only one that news click. They covered more than the 20 times in this one and a half years time. The people's voice way can hear they given the space for the marginalized that is the reason they want to government want to crush. It is not that the including the ruling party also receive the money and everybody to run the show, they need a money. There is nothing. Nobody is violating. If they're violating, you have to prove and you have to show the proof and you can do. You cannot crush the media, just stating something. But the truth is actually they have given the voice for the all the marginalized. I don't want to use the voice layer. The marginalized also has the voice that voice they have given in the echo way in the whole media world. That is the crime that state is doing. But I salute even the news click. They're still giving the same voice even without the profit even today. And the state cannot crush that voices at all in the theater or any day.


Ooh, it is official. It is time for Shom Scoops. Look, last time we all hung out, we found out Dremont Green's suspension. It's indefinite. Shoms, any news there? Yeah, there's an update. I'm told Dremont Green has begun counseling and people around, the warriors, people around Dremont Green, they see that there's a level of understanding and really grasping that there's a process that he's gonna go through and undergo to make sure that he's gonna return under a full capacity. He's been feeling bad about what transpired. And I'm told the expectation is that Green will remain sideline via suspension for at least the next three to four weeks. And that means that his suspension was stretched at least approximately 12 games. And at that point, making sure that when he's back, he is actually back. There's not gonna be a blip. There's not gonna be a recurrence of any more from Dremont Green. And I think this process, from what I'm told, it'll also consist of regular check-ins with the warriors, with the league, as him, the team, his agent Rich Paul, the league worked together on his return process. But it's gonna be at least the next few weeks for Dremont Green. Chandler, what do you think about it? I mean, I heard Shaq the other day talking about, you know, this is just Dremont. This is how Dremont is. But then he is getting some sort of a help. What do you think? Well, I think he's taken the proper measures to get better, right? He's starting therapy and the growth of him becoming a better person is hopefully on his way.   I guess we'll wait and see. But I'm happy that he's taken the proper steps because, again, we say this isn't about basketball anymore. This is about him becoming a better person. Because if this lingers, and this lingers into his personal life or this lingers off the court, then he's looking at some real issues. So he's gotta get this under control. This is more important than the NBA, or this is more important than any game or fine. He's gotta get better as a human being and as a person. And he seems to be taking all the right measures to get there. So hopefully it's not just a PR stunt. And hopefully he's actually bettering himself during this time. Shoms, we're gonna talk Bradley Beal here. I can't believe I'm about to ask you this again, but a different injury this time against the Knicks, what can you tell us about his status? Nasty right ankle sprain. It looked really bad. Good news for Bradley Beal, his X-rays MRI showed no fracture in his ankle. But I'm told he's gonna be out at least likely a few weeks, at least three weeks for Bradley Beal that he'll be sidelined. He's only played six games this season. It's just another setback. He's dealt with back issues. We've talked about there's been nerve issues with his back. And now there's this ankle issue. The son's big three just got back on the floor last Wednesday. They were playing in their second game. They haven't even played two full games together as a big deal with Kevin Durant, Devon Booker and Bradley Beal. And now Bradley Beal is gonna be out at least the next three weeks potentially. So it's a tough setback for Bradley Beal and he's gonna have to rehab just another injury. It's a long, it's a growing list, Chandler. I mean, if you're Bradley Beal, if you're the team, how do you deal with this list that continues to get longer, not shorter? Well, this is just brutal, right? Cause this is a freak injury. And when you work and you grind so hard just to put yourself in the situation to get back and then something like this happens where it's just completely out of your control and you land on a guy's foot. And now you have to deal with that. Now it's a separate kind of agenda that you have to take. And I know he's feeling the pressure and the expectations and think about how much we all wanna see this big three together. And it sucks because the timing of it, as a team, they need to get these reps that are valuable. Yeah, this is ugly. Also, he jumped so high on his jump shot. It's like the worst guy for what happened to.  So it takes a toll on you mentally. Brad's a strong dude. He's gonna get back from this, but as a fan, we wanna see this big three, right? We wanna see how good they can be. We talk about the West is wide open. This is probably my favorite team when healthy, if they can get healthy, which seems like they're not gonna for a long time to be there at the end and contend. So I feel for the dude and hopefully he can get back on the floor soon, but this is a tough blow after someone going through all of this rehab for his back to have this happen to him. Yeah, and the other thing with Lou is, I always wonder as fans, we look at some players as just being injury prone. Unfortunately, they have bad luck, right? They get the bug. And I wonder as a team, when he does slowly make his way back from this injury, how cautious do you have to be? I don't know if you'll be cautious with an ankle injury, especially if it's like a high ankle sprain or something like that. Once he's available to play again, those injuries are usually not something that's gonna be reoccurring. That's something that you're gonna re-aggravate. When you're over an ankle sprain or a high ankle sprain, it's usually over and done with by the time you're back on the basketball court. And listen, once he's back, we're talking about another month from now, three weeks to a month from now, I don't think they have the luxury of waiting. I think they gotta start really juicing this group up and get them going to the group that they're gonna need to be in the postseason. So cautious, I don't know if they go on a side of that. I think they just put them out there and play the regular minutes that he was capable of playing. He was out with a back injury. He was playing upwards of 25 to 30 minutes. So I don't see that being an issue when he comes back. Shoms, we also have a lot of injuries coming out of Cleveland. Like it seems something bad is going on in the air up there. What's the latest with the Cavs? Two significant injuries. One, Darius Garland, their star guard. He's gonna be out at least four weeks. He's got a fractured jaw. Then Evan Mobley, their big man. He's gonna be out six to eight weeks with knee surgery. So these are two key players that are gonna be gone for significant periods of time. They had just won nine of 12 games on a recent stretch. And then they lose three in a row. Then they won Saturday night. So that's a positive that they at least won. But the Donovan Mitchell side of all of this, he's gonna be a topic. He's definitely a topic among teams around the league this year and next season left on his contract. And the Cavaliers know this about Donovan Mitchell. He wants to win, he wants to win big. He wants to compete for a championship. And this team right now is really in that playoff, play-in race. And if they do drop out, I think a lot of teams are gonna be looking into the Cavs. And now this is a team that's been hovering around 500. We're just past the 25 game mark. And so I think these are just two significant injuries for them that they'll have to deal with. Man, those are big ones. And I'm wondering Chandler, we always hear about the Donovan Mitchell overall. He wanted to be a Nick. These injuries are probably not helping whatever that situation is in Cleveland. Do you think something comes out of that? Do we hear more murmurs? I think so. I think that we're gonna continue to hear these rumors of are they moving him? He's unhappy. Cause there's something going on here, right? There's a disconnect. You don't just take this kind of fall-off from last year, getting home court advantage. I understand they lost to the Knicks in the first round, but this is a great young team with a core that I would think would want to continue to grow together. When you look at Mobley and Garland and Donovan, Karris, Jared Allen, they have the talent. They have the pieces and they can continue to get better. They have the coach. I think JV Biggerstaff is the guy for this job. But yeah, when your main guy, Donovan Mitchell, you hear all this stuff and there's murmurs, how he wants out and he's kind of, it's leaking into the locker room. There's issues with him. And then on top of that, now your other two best players are out.  So this is a team that I think had high expectations that we thought would make that jump after last season. And they've gone the other way, which usually results in sort of move. So if I'm them, I'm listening because I don't want to get him the option just to leave and walk and get nothing for him when you can probably get a boatload for him right now. I'll tell you what though, Chandler, I'm listening, but I'm not hitting the panic button yet. This is a team that, my dog's jumping on me right now, but this is a team that's, this is a team that's two and a half games out of the four spot, man. And so even though they're sitting at eight, they put a good week together, put a couple of good two weeks together, they put themselves in a pretty competitive spot. And so am I listening? Yes, if I'm the Cleveland Cavaliers and I'm looking at all the turmoil that we're going through, of course, I'm listening to offers because like Chandler said, I may be able to get a boatload of assets for him. But at the same time, I'm still trying to compete until that day.  The only problem is they now have to do that without Garland and Mobley, which is, that's a tall task. But you still got, you still got down on the Mitchell, you still got a shot. Shams, the world awaits, the news will break. We will see you tomorrow bright and early.


Good afternoon all so I wanted to go over a trade a really really nice technical trade set up on the dollar yen and again if this is not on your list of you know currencies to take then You know, it's it shouldn't really be a trade. You should be taking fundamentally, right? you have to understand why you want to be a buyer of the dollar and You know potentially a seller of the Japanese yen But from a technical analysis perspective I actually really really like this. So Let me break this down. This is a CPR zone, right? It's a CPR zone. So let me just Just give it the context that it deserves so Before We had I guess the the capture Element and what adds to this is the fact that it was a capture that Lots of traders would have got involved in right? So that's in fact, let me just Bring up some volume on here. Yeah, lots of volume on that trade right there Yeah, so the volume would tell you that there was lots of trading activity and what happened on the Friday We basically got one nine is it nine Seven I think it was one nine five one nine seven K jobs And there would have been a lot of traders getting short on this news right on this bad news You know getting short it was a nice area where prices have come up if you think about the location where it was Traders are probably anticipating during the London session that maybe potentially it wasn't going to go in its direction You had a little bit of a you know resistance their level traders are waiting they're waiting and waiting it pops up the the level obviously the The number comes out it starts to sell off right everyone's involved in that short everybody's no one who's getting long in this in This trade especially after this disappointing Number but then what we see in fact is this so they basically committed capital, right? They've committed a lot of capital This is where the capturers Traders commit capital loss of version bias kicks in yeah as prices start to go higher It doesn't let anyone who went short off the hook at all. Yeah, doesn't let them off the hook Right look at the pain the amount of pain that these guys are in now Whoever went short here if you haven't been stopped out loss of version bias you're moving your stop loss thinking It's not going to go above that level and surely sure enough. It does lots of pain involved in here. So The relief the majority of the relief I think is going to be somewhere in and around this area now Capture pain relief is really the study of obviously trading psychology, but also where the Most amount of supply and demand orders will be from a purely from a Technical analysis perspective. So when you think about what price does come down for example to example here Yeah, there's going to be lots of traders getting involved in this area. You've got a nice area of you know resistance Resistance is going to be an obvious level But most of the traders would probably got caught down here now Of course depending on where you taste a stop loss you might you might get up for a small loss But I think the majority of traders are in and around this level here So again, I can't necessarily predict but you know price is going to do but I would Guess that my best guess if prices do come down here Rather than necessarily getting involved in here, which you can of course you can but just understand that if you get Stopped out in fact that level is probably being stop-hunted right because it's such an obvious level And there's going to be lots of traders, you know placing their stop losses below that level But this is really I think these areas here where the 1180 and the 11 You know 50 lab area will be where prices may start to reverse. This is where I think the majority of Orders because if traders when it's short here, then they have to do what to exit they have to buy to exit This is where a lot of the buy orders are going to be in and around these areas here Yeah, trade is taking profit of course are going to take a profit here But also other levels of support and resistance by all I ultimately think that the 1150 and even if you look at it From a discount perspective, this is the new low. This is the higher low higher high Right from here to here.  Yeah This is going to be the most bargain area you can think of you know recent bargain Anyway, this is just below the sixty one point eight percent fit probably. Let's have a quick look. Let's have a quick look Sixty one point eight percent fit retracement. Yeah, so that's going to line up really nice in fact Really nice for traders to actually get long in and around here Now, I don't know like I said, it could of course it could come down here and fly off the handle Right could continue to go higher. Who knows I don't know but the the ultimate I think I do think the better trade would be for To go long in and around this area here Of course, you can try a couple of trades if this is in your You know your portfolio to try to look for trades, but it's going to be in and around this area Nobody knows where prices will exactly reverse from if they will even reverse at all, right? You don't know From a daily timeframe perspective, you know, you are buying potentially a you know the the highs but even from a daily perspective, let me just Kind of pull that back That area in fact it lines up that lines up with a nice sixty one point eight percent fit, right? So just where we are let me go down and take us the hourly Yeah, that in fact is that has a lot more confluence and that's not to say that, you know, sixty one point eight percent fibs are You know the the the thing to trade. It's just understanding why there's going to be lots of Demand in and around this area, right? And if you look at the higher timeframe from a daily fit perspective higher low higher high That looks, you know a lot had looked to have a lot more confluence in this area rather than, you know, that top area there You know, I mean so I think overall This is a really really really nice trade really kind of driven by the fact that lots of traders lots and lots and lots Of traders have been caught that volume candle look at it is literally above everything else By a massive long way apart from the last time it was it was again another I think it must have been another FOMC announcement or something like that maybe 20 seconds. Yeah, put it some bank announcement right there 22nd of September Another one right here. So Not only is it great technically from a psychological perspective and just understanding that trade is definitely going to be in this trade That is beautiful. So Again, nobody knows risk of could come into the market. There could be something, you know Terrible that happens to the dollar the market might not believe, you know things can change Nobody knows but the thing is is that if prices do come down here and you do want to be a buyer of the dollar I think that is a really really really top quality Trade setup and again good trades can lose bad trades can win. It's just a random single event and We just have to accept that, you know, if you are looking to take it, but I think it's a brilliant trade technically and I do like capture pain relief trades that have an element of news And traders being caught by the wrong side of the news and I think probably probably 99.9% of traders generally would be caught By this move right because we were looking at potentially getting short on the dollar until you know The news came, you know, we read over the weekend that in fact, you know, the Federal Reserve are looking past that, right? So you can guarantee that other traders are getting involved in that trade for sure So it's got lots of confluence in around that area. Anyways guys take care and speak to


Or are you all still out there? Cool, good, well, I've never actually done the 5k, but I've always wanted to, and then I find out it's at like seven or something, and that's when I wake up. Hot, go running, so. Cool, well, I wanna first say thank you to the organizers. This wouldn't be possible without them putting it all together and bringing us all here, so let's give a round of applause for organizers and sponsors, and everyone who makes it happen. So I'm Eileen Yuchitel. I live in Kingston, New York. It's about two hours north of New York City, or a seven and a half hour drive to Pittsburgh.  You can find me anywhere online at the Handel Eileen codes and I very rarely but occasionally blog at EileenCodes.com. I'm a senior systems engineer on GitHub's app systems team. We do a lot of stuff with open source and Rails and Ruby and Rack and how those interact with the GitHub application, keeping GitHub up to date, or at least trying to get it up to date on Rails. We'll get there eventually. I'm a member of the Rails core team. For anyone who's new to the Rails community, the core team is responsible for defining what the future of Rails is going to be and we are responsible for making releases, releasing releases, fixing releases, and all the good and bad things that come along with releasing new versions of Rails. So if you've been in the Rails community for any amount of time or just saw Mark's clickbait title yesterday, you've probably heard the phrase Rails doesn't scale. We've heard it on Hacker News, we've heard it in VC meetings. Recently, we heard it in the misguided Vanity Fair article about Twitter with the claim that they couldn't effectively combat harassment because Rails was just FisherPrice software. It's funny they called it that. I know they meant it as an insult saying Rails was for children and not serious adults with serious web apps, but FisherPrice and Rails are alike and that they are robust, well-designed and unforgettable. The interesting thing about Rails getting a bad rap for not being scalable is that it's taken many companies to a scale they'd never dreamed of. If Twitter had tried to build their app to handle the scale it is today, they probably would have been bankrupt before they had a proof of concept. The reality is that Rails does scale. It just doesn't scale easily yet. Historically, Rails hasn't done a great job at making scaling easy. While we pride Rails on developer happiness, we were missing the mark of scaling and frankly falling short. In this talk, we're gonna look at ways in which Rails was not scaling easily and what we're going to do about it. I want scaling Rails to be as enjoyable as running the Rails new command. Scaling means different things depending on who you're talking to or who is trolling you. Or what your app is supposed to do. For the purpose of this talk, scalable means that literally over time, an application's growth in code, data, and traffic doesn't really change how well it performs. While Rails can't take on every part of scaling your web application, there are two important areas that I want to focus on. The first is that when you're scaling your web application, your test suite shouldn't block development. As an application grows, new code shouldn't really cause a ton of friction. Developers should be able to easily prototype and build features quickly without being hindered by the time that it takes for your test suite to complete. While we've made many improvements to test performance in the past, it's really no replacement for concurrent testing. The other area that Rails was failing to scale easily is that as your application grows, it should be able to handle increased data and traffic over time. The database shouldn't just crash because you got more users or because you have too much data. It should be easy to distribute the load on your database as your traffic increases. Rails has had support for multiple databases, but that support is undocumented, hard to understand, and difficult to implement. While Rails can't take on scaling every part of your application, I believe that we can improve the developer happiness around these two main issues. My goal is to tackle these issues to make Rails 6 scalable by default. Scalable by default means that it's easy for engineers to scale their Rails application without having to spend hours writing a custom setup or using a lot of outside tools. Scaling your application doesn't have to be hard and Rails should be able to take on at least some of that work for you. Some of you may be thinking, hold up, wait, Rails 5.2 just came out. Why is Eileen talking about Rails 6? Well, major versions of Rails allow us to reconsider what's possible. It's going to be a while before 6 is out, but I wanted to share my plans with you. In the past few months, I've got a lot of work to refactor Rails and add features to make scaling easier. We'll look at the work done to speed up your test suite and improve Rails' multiple database handling to ensure that scaling is simple and intuitive. So the first feature that I'd like to introduce for Rails 6 is parallel testing. The parallel testing feature will allow you to run your test concurrently using either forked processes or threads. Parallelizing test suites is an important part of scaling web applications because as you add more code, the more tests you will add, or should be adding, and your test suite will become slower and slower over time. Sure, you can mock a bunch of calls or ensure you're not making external requests or building a lot of data sets, but that still won't speed up the time it takes to run 10,000 tests linearly. Parallelizing large test suites can significantly reduce the amount of time engineers need to wait for your builds to finish. A lot of other companies like GitHub, Basecam, and Shopify have been writing their own parallel testing implementation for years. The problem with all of us writing our own implementations is we weren't sharing our ideas with the broader community. Rails is popular for taking the complexity out of your app and turning it into reusable generic chunks of code. By adding parallel testing to Rails, you can reduce the complexity of Rails applications, set a standard for parallelization, and make it simple to scale your test suite. Earlier this year, Aaron Patterson and I worked together to write the parallel testing feature in Rails based off the parallel testing infrastructure in GitHub. While inspired by the GitHub code, the code in Rails has been rewritten to have a smaller footprint, be more generic, and a lot easier to use. Rails parallel testing also supports multiple databases out of the box. This was a requirement for us since we use a lot, we use multiple databases in GitHub in all of our environments. The concurrent test runner in Rails 6 can parallelize your test suite by using either forked processes or threads. First let's take a look at the implementation for the forking parallelizer. Forked process parallelization is implemented in Rails 6 using distributed Ruby, also known as DRB. DRB is a distributed object system for Ruby and can be implemented with zero dependencies. Distributed Ruby is really cool and it's one of those features that I don't think gets a lot of attention so I encourage you to check it out. Parallelization is invoked in your test, in your test, through the test helper with the parallelize method. This method takes a worker's argument that you wanna fork by. Parallelization with forking lives in active support and is backed by many tests parallel testing feature. When you start your test suite using the forking parallelizer, the testing parallelization class will be initialized with the number of workers you requested. In the initialize method, we set a queue size, a queue, a server, and a URL instance variable. The URL starts the DRB server locally and represents the URI for the server to bind to. Parallelization in Rails is supported by many tests so once this class is initialized, all the other methods within the class are actually called by many tests, executer, and parallelizeMe. From here, many tests will call the start method in the parallelization class. Start sets the empty pool array to a block that forks the processes based on queue size. Start then calls this after fork hook. This is provided so that active record can hook into the parallelization and create a database for each process. Start then creates a DRB object which represents the queue of work to perform and will maintain a reference to the DRB server. The DRB object queue variable is used in this loop to split the work for each process. Inside the loop run one method is called which will run the tests assigned to that process. Many tests will return a result and the queue variable then calls record. Record sends the reporter and the result so that at the end of the test suite run, each process can report which tests passed and failed. At the end of the start method run cleanup is called hook is called which allows active record to delete those temporary databases that were created in the after fork hook. And finally many tests call shut down which will empty the queue and wait for each process to terminate. And that's basically the entire implementation of work process parallel testing in rail six. As you can see the underlying implementation is really simple and it's only actually about a hundred lines of code. Don't worry if you didn't follow this though you don't actually have to know how any of this works to use parallel testing in rail six. For newly generated rail six applications, parallelization will be automatically included in your test helper and for upgraded applications you only need to add a call to parallelize in your test helper. The parallelize method takes a worker's argument that accepts an integer. The default number of workers is two which means that rails will automatically fork your tests into two processes and create a database for each process to run your tests against. Each database is suffixed with the worker number starting with zero. The databases are generated in the after fork hook that we looked at earlier. The databases are then automatically deleted in the run cleanup hook right before processes are terminated. Active record and parallel testing does all of this work for you so you don't need to do any of it. If you're using multiple databases in your application rails provides two callback hooks to handle your secondary or third or fourth or hundredth database. The parallelize setup is called via after fork and can be used to set up your secondary database. The parallelize tear down method is called by the run cleanup hook and can be used to clean up your fork databases. I get how we have a whole lot of complicated code to make this happen. So once we're on rail six this is going to be a very welcome abstraction. If you're using a single database as most applications are then you don't need to use these hooks because rails will automatically create and delete the databases in apps when as you're running the tests. As you can see the API for forked parallelization is relatively simple and easy to use. So the other type of parallel testing that rail six provides is threaded. You'll want to use threads over processes in a few cases. You'll need threads if you're using windows because the Unix sockets that DRB relies on aren't supported and you'll also want to use threads if you're a J review user. The last reason that you may want to use threads is if your tests are IO bound. Most of your tests are not IO bound but if they are they're going to be faster with the threaded parallelizer because they won't be waiting for the processes to finish before running the next thing. The caveat though is though that your code has to be thread safe to use the threaded parallelizer. The parallelize method takes a second optional argument that default called with the defaults to processes to use the threaded parallelizer in your application set with to threads. It's that simple. The parallelization setup and tear down hooks are not supported by the threaded parallelizer because it only uses a single database. One thing to keep in mind is that running tests in the same suite cannot use different types of parallelization or number of workers. You can't pass five workers to 100 of your tests using threads and processes for three workers to the rest. If you need that kind of behavior you should split your tests into two different suites. Threaded parallelization in Rails 6 uses many tests threaded executor. One of the differences between the implementation of forked process parallelizer and the threaded parallelizer is that we didn't have to write any of the code for the threaded parallelizer in the test suite. Many test parallelizer uses threads already so we simply just added a conditional that initialized that executor instead of Rails parallelizer. So we originally, Aaron and I originally didn't want to implement the threaded parallelizer because frankly threads are really hard to get right but I felt it was important to support threads out of the box for RJ, Ruby, and Windows users. An example of why threads are hard came up while Aaron and I were working on the threaded parallelizer. We were running our tests and we were suddenly seeing that everything was sort of randomly failing. Deadlocks, sometimes data was left behind. It was really strange. Some runs would pass but almost all of them would fail. We first thought it was related to the fact that my demo app that we were running the tests in was using multiple databases. So I switched to a brand new app that had a single test database but we saw the same issues. Running a single test always passed so we knew that it was something to do with concurrency. To look deeper at the problem we hacked the test log to display the connection ID for each connection to the database. Each thread should be connecting to the test database with its own connection ID. But what we saw instead was quite opposite and quite wrong. Each thread was connecting to the database with the same connection ID. And Aaron says to me, this is so weird. All the databases are using the same ID. We seem to have an isolation problem. And as he said those words, I suddenly knew that it was all my fault. I realized in that moment that code I wrote in Rails a year ago was coming back to haunt me. How many of you in this room remember system tests? Well when I implemented system tests I wanted to do it in such a way that we didn't need to use database cleaner anymore. The underlying problem was that when system tests are run Rails opens a connection to the database on one thread and then Capybara boots a Puma server which opens a second thread and second connection to the database. This meant that in system tests Rails thread and the Puma thread couldn't see each other and we would get inconsistent data between test runs because the transaction and the Rails thread didn't know about the data on the Puma thread to roll it back. The way we fixed this problem was to force each thread to use the same connection. Do you see where I'm going with this? The change that I implemented in the fixed system test is the exact change that broke parallelization because the change required Rails to tell all of the threads to use the same database connection. With parallel testing we want the exact opposite of that behavior because the threads aren't trying to share data and transactions like system tests are. For effective threaded concurrency each individual thread should maintain its own connection to the database so that the threads aren't influencing data on each other. Luckily, since I implemented the offending code it was easy to find and fix the problem. I simply added the ability to internally configure the setting so if you're using the threaded parallelizer the threads will each open a separate connection to the database. This does mean that system testing is probably not possible with the threaded parallelizer. I mean, I know it doesn't actually work. There might be a way to make it work but I didn't do that. Considering that the change to fixtures for the system test threads is the exact opposite behavior of what we need for the threaded parallelizer I don't know how well they would have worked even if I hadn't broken them in this way. If you want to use parallelization with system tests I do know that processes works. So running your parallelized tests doesn't require any extra work on your part after you set them up in your test helper simply run Rails tests like you normally would and Rails will handle the rest for you. Sometimes you may want to change the number of workers depending on the environment you're using. For example, you may want to use two workers locally but 14 workers on CI. So Rails provides an environment variable called parallel workers which will take precedence over the number of workers passed in the keyword argument. If the number of workers is one or fewer parallelization will not be implemented because you need more than one worker for it to actually function. If you're interested in the PR for parallel testing you can check it out on GitHub. Parallel testing is going to be a great feature for improving the speed of your test suite. I'm really excited for this feature and I hope that it helps you scale your application's test suite so that you can focus on deploying code instead of waiting for CI to finish. Now that we've got your test suite squared away let's take a look at the other way that Rails doesn't handle scaling well today and that's whether your application can handle a spike in traffic. I'm not talking about DDOS traffic. For that kind of spike you want to use an outside vendor or higher experts that can mitigate that for you. What I'm talking about is trying to scale your web application because Justin Bieber came along and started using it. You need to scale fast and you need to scale yesterday. I've been in these situations before and it's not fun.   It's at this point you know that you need to split tables off your main MySQL cluster. You need read and write and read only databases. You need replication and you need more capacity.  Rails has had support for multiple databases for a while in that you can do it. We do it at GitHub so it is possible. But it's hard, really hard. It's so hard that it took me three hours to build multiple databases into a demo app in Rails 5 and I already have done it before. I don't know how long it would take someone who's never worked on this kind of stuff. The reason it's hard is that Rails hasn't been setting a standard. While the underlying plumbing works great, we weren't exposing it through good documentation or the tools that you need to make it intuitive. So the second Rails 6 highlight that we're going to talk about are improvements to using multiple databases with Rails. While these aren't punchy brand new features like parallel testing, they're an important part of scaling your web application. Multiple databases are useful if your application is getting to a point where a single database instance can't handle all of the traffic reading and writing from it. If your application is going down because your database is crashing, you may need to split tables off into separate clusters or add read replicas to alleviate pressure on your primary database. At GitHub, we have multiple top-level primary databases that have write roles as well as read replicas for each of them. Rails has for a long time supported multiple databases and thanks to work from Arthur Neves and Matthew Draper, Rails 5 is a ton easier than it was in Rails 3 or 4. However, when I set out to build that demo app that uses multiple databases, I quickly realized there's a lot missing. Let's take a look at what an application with multiple databases looks like and along the way, I'll point out where Rails was failing to make it easy. Let's say we have an application with two databases. One is our primary database that has a flowers and people's table and the second is an animal's database with a cats and dogs table. By default, ActiveRecord knows about the primary database and connection because that's attached to ActiveRecord base. We need to tell our application how to connect to and talk to the animal's database. However, before we get started working on our application, we already have a problem. Best practices for multiple databases aren't documented in Rails. We have no documentation for how to set up your database YAML, your models and connections, your migrations or your rate tasks for the second database. Based on our setup at GitHub, I originally set up my database YAML like this. Here we have a two tier configuration with the default production namespace and a second namespace called production animals for the animal's production database. While this way may make sense or maybe the way that previous blog posts have said to do it, there's no longer the recommended way to set up your database YAML for multiple databases. If you're using Rails 5 or higher and need multiple databases, you should set up your database YAML using three tiers like this. The three tier config allows us to group all of our databases by their respective environment. This leads to a cleaner database YAML and it makes it easier to understand how everything works together. Primary is the default for your main database. This technically can be called anything, but I really just recommend you keeping it primary so it makes sense. This would represent your original production database. Then we have the animal's entry, which will hold all of the dogs and cats tables. With the three tier config, we know exactly what databases are tied to the production environment versus how the two tier config used to work.  It's just if you're using three, multiple databases. Once we have the databases created, we need to tell active record where the migrations for the dogs and cats tables live. So I've worked with migrations that deal with multiple databases before and there's a few ways to do it. You can hack your migrations to set the connection at the beginning of the migration. This is the way we do it at GitHub and I can tell you that I do not recommend it. So my preferred way is to put all of the migrations in the animal, for the animal's database in their own directory. It's cleaner and easier to group migrations by connection rather than putting everything in the DB migrate directory and having to open each migration file to figure out where the table lives. For this app, I moved the dogs and cats migrations into a directory called animals migrate. To use this way of handling migrations however, we need to set migrations paths any time we're going to call migrate. This works fine for the custom break tasks, but it's impossible to use with any of the existing code in Rails because the migrations paths is a class method or was a class method on migrator instead of a method on the connection instance. This means that every time we want to call migrate for animals, we have to set the migrations paths. So we've discovered the second problem with multiple databases in Rails. Rails doesn't really support migrations for multiple connections. You can write a database task that will run the migrations for you, but if you need any of the Rails internals that depend on the migrations path, they have no awareness of anything outside of the DB migrate directory. So the next step is setting up animals connection for the dog and cat models. First, we create a new base class. You can name it whatever you want, but I named it animals base. For this to function correctly, we need to set abstract class to true. This setting tells active record not to use the implied STI table from the parent class for the child classes. For example, we don't want the dog model to look in animals based dogs table, but we want it to look in the dogs table. Then we need to establish a connection to animals, and that's it. Now that our animals base is set up, we need to change our child classes that to inherit from animals base instead of application record. This tells Rails which connection to use when you call dog.new or cat.find to make sure that it looks in the animals database rather than primary. So while we've already discovered some problems with setup, this looks all pretty simple, right? The caveat though is that none of the rake tasks will work for your secondary database. The tasks only know about active record base and have no understanding of animals base. Create, drop, and migrate will only operate on your primary database and not on the animals one, so we're going to have to write all of those rake tasks for each non-primary database. Writing all of those tasks is tedious and time consuming. This is something that Rails should, this is something that you should not have to do. Rails should really be doing it for you. After I created all of the rake tasks, which was probably two and a half of the three hours that took me to set this up, I went to run the create task for the primary database and my application through an error, saying that the production database wasn't configured. I double-checked my rake tasks and even stashed all of my work except for the three-tier config to double-check that I hadn't done anything wrong. After some debugging I found that the default connections weren't working with the three-tier config. When you call rake DB create, it first loads the ActiveRecord initializer rail tie, which calls established connection with no arguments. This is where Rails will establish the default connection to the database. In a standard application with a two-tier config, Rails will assume that you want the database that corresponds with the environment. But when we have a two-tier config, Rails doesn't know which one is the default because there are two per our environment, primary and animals. So now we've defined four areas where ActiveRecord is making scaling your database very hard. There's no documentation, migrations don't work, database tasks don't exist, and the default connection doesn't even work. At this point I realized that multiple databases in Rails applications are still really hard. I know what I'm doing and I worked on like not even just multiple databases in an app but the plumbing of multiple databases before and I still couldn't quickly set up multiple databases in a demo app. Rails wasn't meeting the basic criteria to make scaling your database easy. The scope of my original project upstream some of GitHub's multiple database behavior to Rails had grown enormously and it started to look like I was going to have to do a massive yak shave to accomplish what I wanted, except instead of having one problem to solve I had three massive yaks to shave. Each of these problems was going to be time consuming and there was no easy way to solve any of them. It's easy in situations like this to get overwhelmed and frustrated. And believe me, quite a few times I had wondered why I'd even tried to upstream any of GitHub's multiple database behavior to Rails at all. But then I remembered that I proposed to talk to RailsConf and then they asked me to keynote and so there was no way I was gonna back out of that. So the first thing I decided to fix was handling for migrations. It didn't make sense to start with fixing documentation because shaving all of the other yaks was going to change how multiple databases work anyway. I chose to work on migrations because parallel testing needed to support multiple databases and I knew that the parallelized hooks were going to work better if I could fix the migration code. Previously, if you wanted to put your migrations in a separate folder you had to set the migrations paths any time you were going to call migrate and write your own fancy custom task. This is fine if you're calling migrate directly but if you want to rely on any of the Rails internals it becomes impossible to set that path since there's no way to tell Rails what migrations paths to use except for on the class level. This means that your app is always responsible for telling Rails where the migrations paths live because Rails can't ask where they are. It should be easier to work with migrations in different directories. I decided the best way to fix migrations was to store the migrations paths on the connection instead of the class so that Rails can ask the model where do my migrations live instead of having to be told by the app every single time it needed to run migrations. To accomplish this Aaron and I were a factor of migrations paths and you can now set migrations paths in your database YAML. All you need to do is change your app in the database YAML to set the migrations paths to the database, to the file directory that you created so we can set ours to the dbanimals migrate. If you don't set this field Rails will default to dbmigrate. This refactoring moves the information for migrations paths from the migrator class onto the connection. This change makes it possible for ActiveRecord to ask the connection what migrations paths it should use. Before this change this wasn't possible. This looks like a very simple change but required a medium size refactoring to accomplish. We drastically reduced the private API for the migrator class which allows for more flexibility in controlling where migrations are run from. It's also backwards compatible so you don't actually have to change anything in your app until you want to use this feature. Looking at refactoring PRs aren't fun for conference talks so if you're interested in the implementation you can check out the pull request on GitHub. All right so now that one YAC was done it was time to take on the next one. Changing Rails so that you no longer had to write all of the rate tasks for your new database. One of the hardest parts about multiple databases in Rails is that you have to write all of the rate tasks for your animals database yourself. This is extremely time consuming and something that Rails should really be doing for you. My goals with these improvements were to make the database tasks intuitive and predictable. The problem with the existing tasks where the code for dvDropMigrate and create would only operate on the primary database. That doesn't seem very intuitive. If I run create I expect it to create all of them. And there were no namespace tasks for primary animals respectively so even if I fixed the first problem there was not going to be any way to just run migrate on your animals database or drop on your primary. I wanted the existing tasks like rate dvDropMigrate, create, skip a dump, skip a load, all of those to automatically run for both the primary and animals databases. With a three tier config they were only running for the primary database. One of the challenges with dealing with a three tier config is that a lot of the code in Rails assumes that we have a two tier config and the config hash is tied to an environment. When you have a single database per environment Rails will simply select a single configuration hash that corresponds to the respected requested environment. But with a three tier config requesting a configuration hash by an environment will return the configs for that environment, return all the configs for that environment so we don't know which one is the default. With a three tier config we also don't know how many databases there are per environment or what their namespaces are. Configuration as hashes are an inflexible data model because Rails can't easily select the animals database for an environment because Rails doesn't know what the namespace of that database is set to. So to solve this problem Aaron and I decided that we should internally convert the hashes to objects so that we can ask them questions and more easily manipulate the data. We created a new class called database config. With this class we can pass an environment that would correspond with the environment and the first level of the hash. A specification name for the second level that corresponds to the namespace like primary or animals. And a config hash which corresponds to the configuration hash for that environment and specification respectively. The returned object looks like this. Now that we have this object we can ask it questions. What environment is this config for? What specification name is associated with this configuration? And what config hash is associated with the database? These objects are created by passing the entire database YAML hash to a method called dbconfig. This method walks all of the configurations in the database YAML and returns the database config objects. Now that we have these objects it's easy to manipulate the data model. We can collect the configs for an environment using a new method called configs for. This method will collect all of the configs for a specified environment by iterating over the objects, return and dbconfigs. If a block is given configs for or return a spec name that corresponds with the configuration hash and a corresponding configuration hash. If a block is not given the configs for or return an array of configs for that environment. So in the case of our application that we looked at earlier if we pass production to configs for we will get an array of database objects for the primary and animals production databases. By converting the hashes to objects we have more flexibility and control over the return data. We can ask the objects questions or enumerate over the return database configs with group by or find. This gives us the ability to more easily manipulate these objects. Let's take a look at how we use them in our to fix the database commands. In Rails 5 the migrate task was like this. It simply loaded the config and called migrate. Because it relied on the existing database connection this method would only migrate the primary database in a three tier config. To change this to migrate both the primary and animals database we use the configs for method to iterate over the databases and migrate them. First we pass the rails environment to configs for which will recollect the configs tied to that environment. When using a block configs for return the spec and config we don't need the spec name so we just have the underscore. Then we establish a connection using that return config and then we can call migrate which will migrate all of the databases. Because of the migrations paths refactoring Rails knows exactly where your migrations live so we can run the migrations for the primary and animals database respectively once it gets to that database in the loop. The changes for drop create and migrate commands are basically the same. Collect all the configs for the requested environment loop through them, establish a connection and perform the requested action. Now all of these tasks will operate on all of your databases. So now that these tasks operated in a predictable way it was time to build the dynamic tasks for each database in the configuration. I wanted the tasks for each database to be easy to discover and simple to use. To do this I decided the best way was to suffix the database commands with the database namespace. This way they're intuitive because they read like English hey database create animals and are easy to discover because they show up in the rake tasks list. These tasks are useful if you want to operate on just one of your databases for a specific environment. This would allow you to drop the animals database but not the primary or migrate the primary database and not animals. This gives you the same flexibility that you have in a same flexibility in a multiple database application that you have in a single database application. To accomplish this we collect all of the config names inside the migrate namespace loop through all of the specification names to create the namespaced task. Then using the spec name and environment we request the configuration with config for Envin spec. This will return a single database config object based on the environment and specification name. From there we establish a connection using the config so that we're attached to the correct database and finally migrate that database. This doesn't look complicated but trust me figuring out all of the required pieces and refactoring that we needed to do to make these tasks automatically create themselves took a really long time. I'm not going to show you all of the tasks and how I wrote them because they're all generally the same. For each database we create a command that loops through the configs, create the namespace of the task and then calls the methods for that task. If you're interested in the PR for the majority of this work you can find it on GitHub. Fixing migrations and adding improvements to the rake tasks drastically improves the experience for multiple databases and rails. These changes create an intuitive experience for working with multiple databases. There's still a ton of work to do to make multiple databases truly scale and rails but these changes are a big difference. As you know we still have one yak left to shave. The fact that default connections for three tier configs don't quite work. I've added a Band-Aid fix for this problem but I know that it is not correct and I'm trying to fix it the right way. After trying to force rails to work as is we've come to the conclusion that we need to spend time refactoring active records connection handling to be able to actually accomplish what we want. Aaron and I are working on changing active records underlying connection management to use the database config objects that we looked at earlier. This will allow us to more easily select the config that we actually want to connect to. This is a huge undertaking and connection management in rails has worked from a slightly larger yak into my personal white whale. One day I will defeat it but that work is neither complete nor interesting to look at. I hope the next year at RailsConf that I can talk to you about all of the features that will be possible after we finish this refactoring. There's a ton more work to do to make multiple databases in rails actually simple to use. I want to add nice APIs for rewrite splitting some performance improvements and that documentation that we talked about earlier. My hope is that the work that's been done so far and the connection management refactoring inspires more changes to scaling the database side of our Rails applications. I'd like to thank my friend and co-worker Aaron Patterson for working with me on these features. He started the work on parallel testing and helped me navigate connection management in Rails. I would not have finished any of these features if it wasn't for his help. So a couple of weeks ago someone asked me, aren't you concerned that Rails would become bloated with all of this scaling code? This is a valid point. Most apps don't need GitHub scale. But when I look at the ways in which GitHub has forced Rails to scale over the years, I can't help but wonder, what would Rails look like if we'd upstream these features five years ago? Would more apps be using parallel testing and multiple databases? Would we still be saying Rails doesn't scale? Or would we instead be asking, how can we make Rails scale even more? This past year at GitHub, I worked on upgrading our application from Rails 3.2 to 4.2. Through that work, I got to see all the parts of GitHub's stack from Git code to Wikis to Gist to pull requests to how Git actually works to our database infrastructure, ICI tooling, and our deployment code. I got to see all of the decisions made over the last 10 years, the good ones and the bad ones. That scaled GitHub to where we are now. I know that we're not the only ones who forced Rails to scale. I've worked on custom multiple database setup and parallel testing at other companies before GitHub. I know that Shopify has their own multiple database and parallel testing setup as well. I started to wonder why we were all built the same tools, but we weren't sharing with each other. And I think that comes from when we, the royal we, I'm not passing blame onto anybody specific here, think that our scaling problems are unique and special. This thinking means that when we're tackling problems in our application, we tend to look inward for a solution. You've got to fix that bug or that performance issue. We need multiple databases and Rails doesn't support it. Our engineers are complaining about CI time and we need a fix and that fix needs to be done yesterday. These kinds of emergencies cause us to spend time writing band-aid fixes instead of building a scaling solution upstream. When we're in a stressful situation, it's easy to say, let's just fix this now and we'll come back and build it right later. But later never comes. These patches have a way of taking on a life of their own and they grow and they grow and they grow until you don't know where your app ends and your framework begins. Our applications begin to resemble a game of Jenga, one wrong move and the whole thing comes down. And when that happens, we start to think that maybe they were right. Maybe Rails doesn't scale, but what's not scaling is the code that we wrote. Instead of building generic tools upstream, we build more and more on top of our fragile application. When we build tools while only looking inward, our code becomes specialized, rigid, and impossible to change. The tools we built stagnate because they don't benefit from community improvement. On top of that, we end up building the same tools over and over again. There's a better way though. We need to start looking at our problems from an upstream first point of view. The first step is admitting that our applications aren't special. If our applications are successful, we're all going to need to scale, so why are we hoarding the solutions to those problems? I've seen many companies reinvent parallel testing, hack together multiple database handling, and force their apps to scale inside their application rather than building a scaling solution upstream. I'm not claiming that upstreaming is easy, but when we see ourselves building the same patterns over and over again, it's time to ask, is this problem truly unique to my application? And when it's not, it should be upstream to Rails or built as open source. Upstreaming your code first has many benefits to your organization and your community. Upstreaming your tools forces you to write generic code. This prevents your application from becoming tightly coupled to your tools, which will keep your code more flexible and easier to change, less like Jenga or like Legos. Upstreaming scaling solutions means that you're training your future workforce. Your engineers don't need to learn how to implement multiple databases for your setup because your setup is everyone's setup. Rails will set the standard for scaling databases, so you don't need to redefine that standard at each new company you work at or each new application you build. And lastly, an upstream first mindset means that we're giving back to the community and that community gives back to you. When you push your code upstream, you stop porting solutions that aren't unique to your application, and others are able to use your tools and improve upon them. This is what makes open source magical. I know that by upstreaming multiple database handling that not only will other companies benefit from it, they're going to improve it for me too, so I can do less work later. Working by yourself in a vacuum isn't fun. When you share your experience and your code with others, you learn from their experiences. For years at GitHub, we've been hacking our application to scale, and it's time that we started giving back and sharing our experience with the community. In order to improve Rails scaling ability, I looked at all of the ways in which we forced Rails to scale at GitHub. I've worked on these tools before, but seeing them at GitHub scale really showed me how much Rails was missing. Over the last 10 years, GitHub has learned a lot from using Rails. We've learned where it stands up and we've learned where it falls down. And now we're giving back and upstreaming that scaling behavior because we know it's not special. By building these tools in Rails, we reduce the footprint of our application, train our future workforce, and give back to the community. I want everyone who uses Rails to experience that developer happiness, not just of the Rails new command, but five, 10, and 15 years later. But they can only continue to experience that happiness if Rails is providing the tools they need to run their application for 15, 20, and 25 years. So to answer the question, do I think Rails will become bloated with scaling code? My answer is no, because contrary to popular opinion, Rails isn't dying, it's maturing. If Rails wants to continue to be the choice for web applications, we, the Rails team, need to respond to the needs of those applications. We need to be built not just for prototypes, but for the long term. The path to maturing is to start building scaling solutions upstream so that our users don't need to constantly reinvent the wheel or worse, look elsewhere. Some may still think that Rails is just Fisher Price software, but like I said earlier, Fisher Price and Rails are both well-designed, robust, and unforgettable. We'll keep adding improvements to Rails to make it more scalable, more resilient, more unforgettable. We'll take your apps from Rails new to Rails scale. We'll keep improving Rails until everyone is saying, Rails does scale. But to do that, I need your help. I want you to go home and look at your applications. What have you done to force Rails to scale for you? What can you give back to our community? Can you make parallel testing faster? Do you have other things in your multiple database handling that I don't know about? Do you have other tools that you built that can be made generic and pushed upstream? Rails is and will continue to be defined by its community. Help us define the future of Rails. Let's make Rails 6 scalable by default. Thank you.