When you're writing fiction. What's your first name? Hi Maddie. She said when you when you're writing fiction How do you create character and how do you avoid creating? Same old character That's a hard one next question for mr. Can't You write a lot about this in on writing I think that I Think that the way that I would answer that is first of all you start with the idea that for most of us We think that we're we're good guys. We think we're the good guys. We think we're on the side of angels and so My idea is everybody has some part of their character That's admirable. I'm sure that at one time or another Theodore Bundy helped an old lady across the street, of course He probably raped and murdered her on the other side, but that's that what I'm talking about That's the yin yin and yang of it. So I have a tendency to start Totally Unjudgmental I and that's that that's part of the benefit of working story rather than plot Our lives develop naturally and our characters develop naturally over a period of time And they are influenced by a lot of different characteristics and the way that we look at other people is Influenced to over a period of time as we get to know them Sometimes women that you didn't think were You know particularly good looking you get to know them the more you see them the more you say after all you say oh That woman is pretty and then a year or two later. You say that woman is really beautiful But I didn't see that at first. Do you say some guy? Well, he's just a guy and He's sort of just somebody else that happened to be at this party or in this dorm or whatever And you get to talk to those people a little bit the personality starts to come forward and you start to see The shadows and the depth of things. I've got a character and Mr. Mercedes whose whose name is Holly Gibney and I expected it to be a walk-on Okay, she's this 47 year old woman who still lives with her aging mother and She's got psychological problems and she never speaks above up a Mumble in fact, she's introduced in the book is Holly the mumbler Because she's one of these people we've seen this person. We've all seen this person You can't really say what they're saying you can't really hear what they're saying and they have a tendency to sort of avoid eye contact They might look up every now and then Say a little bit They might have certain ticks habits So I thought to myself Well, I've got a great line for this This this lady The first time that my main character meets her is that a holiday in a restaurant where he thinks she orders a sneeze burger Because she speaks so low. She's actually ordering a cheeseburger So I thought she was a walk-on. I thought she was a flat character little by little She's become more and more important to me and more fun to write about and I started to see that she has an interior life and You begin by observing we I mean You have to look Raise your hand again if you're in the writing courses You have to look you have to see I Mean you can't just Walk and let it all go by it's somebody some of it. This has got to stay you've got to see how people are You've got a look for the person who When they eat they have a tendency to look down at their plate and they're tearing their napkins Have you ever seen a napkin ripper? Okay, or somebody who is in a cafeteria and they've kind of like got the straw in pieces Holly is a lipstick biter kind of like this all the time kind of a She'll talk through her nails So it's it's part of the fun of it to me is to see better and see more you know that famous flanger O'Connor Line about this she says there's a certain grain of stupidity the writer can hardly do without yeah And that is the quality of having to stare. Yeah, so you're hearing you say for Everybody's that when you create character you're really fueled by curiosity not answers. That's right You want to see them grow and they do their own thing if you let them if you let them do their own thing and one of the things that drives me crazy about second and third rate fiction is When a writer will wind a character up and make them go through certain paces And I think why don't you just go back and cut out paper dolls


Is it working? Hello. So hi everyone. Is everyone ready to start? Okay, so Welcome to this workshop about dependency injections and design patterns Great to see so many of you here. The room is cool. This is for us. It's great to see this workshop today is We started to to introduce or maybe craft a bit better to Let you introduce you design patterns a better programming for me personal. I'm a developer And I've been working with WordPress for a very long time But I sometimes miss the things I see in other frameworks like Laravel or symphony But simply because I work with WordPress so much I don't get a chance to really exploit the cool stuff that happens there So this is why me and Elaine I've started this workshop Some some minor things we are short on power supply so we might Have to ask in the in the break if we need to reschedule some people if you're out of power So if you are near a socket Try to work on the socket now so that the rest of the workshop you can do on your battery Sorry for that So about this workshop What we wanted to do is is do something that might be useful in real life. So we're not gonna do Ducks or or cars or something like that. We're gonna work on something. That's actually useful The workshop is Is done in pair programming. So the person you're sitting next to is gonna be the person you'll be working with during this workshop What we're gonna do is we're gonna fake a project and we're gonna introduce business requirements and What we're gonna do is we're gonna discuss this requirement And we're gonna explain what the requirement is and what kind of design pattern or php standard thing could help with this And then we're gonna actually work on it for a while See what kind of solutions you come up with discuss with your partner and once you Once the time is up. We're just gonna present like this is how we did it and we'll discuss Why we did it and how we did it so that way you're not just gonna see Design patterns on the screen. You're actually gonna work with it and then see and working example of it So What are we gonna work on today? We're gonna build a Gutenberg block from And it's gonna show you social mentions So we're gonna build for example a Twitter block and it will are based on if you type in WC IU is gonna Show you all the tweets that are happening about the WCU We we're gonna do just a server-side rendering. So it's be it's gonna be php only we have Abstract everything a way that has to do with Gutenberg. It's in the code so you can see how we've done it, but You'll be just focusing on the actual code implementation the pure logic that's required to solve the business requirements So we're gonna start with the first business requirement We're gonna we have a client fictional and he wants a Gutenberg block that just that shows Twitter mentions So You can read what it's what it's about to do what we're gonna build so I'll give you a few seconds you To read it. I was it So and then we're gonna do the exercise the first exercise is really a thought exercise because we're gonna also use this time to set you up The requirements for this workshop are a working laptop. We're gonna do We're gonna do we need a fresh WordPress installs. You need some sort of local host working and then we're gonna help you through the authentication With the WordPress and a Twitter Gutenberg APIs. It's it's all being automated. So it should be like really 10 minutes We have some TAs over there that will help you Okay, that's some TAs hidden there as well they will help you set up with this Do we have you okay Okay, okay, can you go to the github page of Ellen you will put it in So does everyone have a local host running with a WordPress install if it's a fresh install is the best Because we're gonna add some pages and stuff and it's gonna help if Yeah, so This one has read me this I Take go to the to the repo and Process the read me it says there are what the steps are which what which are required It will we're just gonna use five to ten minutes to set everyone up now and then we can actually Start sorry, it's the wrong one So if you have any questions on setting up WordPress or repo or anything just raise your hand and We'll we'll try to sort it out for you. I'm just gonna take like a five to ten minutes for everyone to set up So just to state the end result should be that you have Installed two plugins that you got from github as Explained in the github repository and activated both of them So for those who are ready you need a wordpress.com account and you need a Twitter account for this workshop Once you have installed those plugins or when you activated all three of them and you go to pages You'll see a few pages that should be generated In in WordPress The pages themselves don't contain any content But if you view them on the front end you'll see you'll see actually some rendering done What what everyone should do is is create a Twitter app and create a wordpress.com app Then once you've done that you can use the page that helps you Generate an open-out token for WordPress comm and once you've done that you can go to the github branches page And then everyone is set up and good to go If you have any questions or trouble just just raise your hand will one of the TAs or myself or Ellen will help out So So these are the pages that you should see and just by viewing them you'll have a brief tutorial on On what to do the nth.php file you can find it in the WCUO 2018 resources plug-in You have a file nth.php there and that's where you'll have to place those tokens So in the meantime for those who who don't use Composer all the time The reason that we're using it here is that we set up auto loading Using Composer so even though for example the resources plug-in it doesn't load in any external dependencies We still use it so we don't we don't require our php classes by hand We just instance new class and Composer takes care of the loading of it So just a quick note Because it might be something that other people are struggling with If your domain that you're using on local machine happens to contain the word wordpress Then this will not work work to create wordpress.com API app because they think you're infringing on their trademarks This will not work. You need to use a domain that does not contain the word wordpress the wordpress.com API Authentication is also Optional so if you really have trouble getting it to work We can still continue with the workshop you will get pretty weird results if you're not Authenticated because it just uses whatever local cookie it finds for your user and gives you random results based on that But the workshop itself will still be able to to to work forward so We need to move on you can continue working on this While while you're trying to get everything set up We need to slowly move on because we want to cover a lot so The git branch that you see printed here. That's the first step in the code that will Provide you with the clean Gutenberg block where you can start implementing your Twitter client But we will not have the time to actually work on that first implementation So we will move on from there But this is actually the code that would provide a clean Clean canvas from which to start the actual server side implementation so We we just assume now that everyone has this Gutenberg block Running with the first requirement all fulfilled with a Twitter API request that fills it with with the mentions on Twitter And now our client all of a sudden gives us a new business requirement. We need to add a second feed So we only planned in the beginning to just implement a basic Twitter API Access so We might even have hard-coded all of the Twitter logic into our code into our block Now the client needs to and needs us to add a second feed to this So this is why we Already requested two different APIs for you to authenticate with the client now requests us to use WordPress.com as well Side-by-side with Twitter so the Gutenberg block is meant to let you choose which network to show The mentions in and then you can dynamically switch between these two the second feed should pull this data from WordPress.com and we want to have the Conditional code be kept to a minimum So we don't want to have a big if else clause where where we basically duplicate the entire code path For doing the remote request and do it once for Twitter and once for WordPress.com. We want to be smart about this That's where Some of the first patterns come into play first I want to talk a bit about instantiation So instantiation is one of the most fundamental aspects of object-oriented programming you create classes and then you can instantiate these classes to have objects and The way you instantiate something controls the coupling between your objects and controls the life cycle of these objects, so Instantiation is is something that should That should get a lot of thought and effort from you to really use it in the best possible way There's a few ways you can instantiate something the most direct one is to use the new keyword in PHP So you just do new and a class name and you get an instance of an object in return And the this This causes immediate coupling to the class that you instantiate it So if you do a new My shiny class then your code is immediately tightly coupled to my shiny class and Cannot easily use any other implementation without first changing that code You also need to know what the constructor arguments are which Oftentimes is pretty simple, but sometimes the constructor arguments might be very complex They might be a lot of work to actually prepare them Step forward from using the new keyword is using named constructors So instead of having the new keyword and one default constructor you can have multiple constructors that create Maybe multiple variations of an object or maybe you have different arguments to create that object so that that allows you To have more control over how something is an instantiate and maybe automate some steps or do some validation etc and Then a step further away from this we get our first pattern, which is the simple factory The simple factory is a pattern that lets you get the instantiation of something of some object Away and put it into a different object so that that object has as its sole responsibility To instantiate another object That might sound a bit Useless at first. So why would I need two objects to instantiate one object? The point about this is that this simple factory can be passed around The simple factory is an object in its own right. So can have its own logic You can you also have this logic encapsulated so you can change the way something is instantiated after the fact after it was Used in some other place of the code and that other place does not need to be adapted So you've put away the exact way of instantiating something so that you have one central place of Changing it in case you need it Here's an example of how such a simple factory could work This is not necessarily the exact code that We would use in a good work block. It happens to be similar here as an example We have social network interface and multiple implementations of this interface and instead of Immediately instantiating a specific implementation We create a factory. This is the simple factory pattern. We create a factory that lets us abstract away the decision process of deciding which implementation to instantiate And here at the bottom you can see how this is used Let's say we have a function that that we pass some string to to denote which Network we need this string might for example be an option in the database or The value of an input field and then we get just past this to our network Factory and the factory then returns Some implementation. We don't need to know which implementation that was returned That is not needed at this point and whatever implementation we get we just use its rendering method so Given that you have multiple ways of instantiating something When should you use the new keyboard? keyboard keyword Because most of the time People just default to the new keyword and use it for all the instantiations that they need The new keyword should only be used for newable types, which is types that That are meant to be instantiated on the spot immediately Exceptions would be an example of this Value objects would be an example that for example the daytime Object you will not create a factory to create implementations of daytime. You will just use it as is And inside of any type of factory, of course you can use the new keyword and ideally the entire rest of your code would not have the new keyword anywhere and as an effect not have any tight coupling to the decisions that are Need that need to be made of which which implementation to use for which interface what comes along with Working with these objects is dependency injection We will have several different examples throughout this workshop of how dependency injection is used I want to start with a quick explanation of it So dependency injection is basically instead of Requesting a given Implementation from within a code. You just have it be passed into the code from the outside from the surrounding code The this Sounds very straightforward, and it basically means in most of the cases that your object has its dependencies Injected through constructor arguments, so when when you instantiate an object, and it needs dependencies Then you instantiate it by immediately passing it the dependencies it needs so that the object does not need to ask for these dependencies itself Here you can see a code example First we have The way of how not to do it We have the mysql database object, and we have some service that immediately instantiates directly instantiates this database and then uses it This is now a very simplistic example, but imagine that you have hundreds of these services which come with direct implementation Access to this one mysql database and now all of a sudden your boss wants you to change to oracle And you have your entire code base riddled with direct references to this mysql database So that's why we want to inject the database instead Here's a simplistic example of this. So we just Sorry, we just have the mysql database as a constructor argument and whatever we get We just store it and make use of that stored version This looks like it's still the same the same code as before, but there's an important distinction if we now extend this mysql database we can just Inject the extended version without this code needing to change because it doesn't include any direct reference to it and As you might even Imagine right now if you use an interface here instead of An actual class then you're even more flexible. You can just have any implementation of that interface being injected So what that causes in the end is the code you're writing it It is very cowardly in that it just defers technical decisions instead of Immediately needing to decide okay, which database implementation do I need we can just say okay This code will work with some database and we don't care which one it is yet We just care about which which data we retrieve So the decision on which implementation to use is deferred to a later moment So we don't need to deal with this decision immediately This also means that the code that we've just built does not depend on this decision and if this decision is ever changed in the future, we don't need to adapt our code because It didn't rely on that decision from the first place and if we now Think through of what that means for our entire application You can say that dependency injection always moves the instantiation of dependencies one level up But it can do this recursively Across the entire object tree or object graph So normally your application is a very complex tree of objects that are interrelated and Dependency injection can move all of the instantiation. So all of the technical Implementation detail decisions Out of the leaves of this tree and up to the root and this is called the composition route So basically what we have is We want the new keywords to all be regrouped in one central location So all the rest of the code if we need to make a change in any of these technical decisions All the rest of the code does not need to be adapted We just make a change in the composition route and that's it. We're good to go Provided that we build the code correctly, of course So There's the next exercise and now it's getting a bit realer So the branch you want to work on is to feed me we want to add the second feed to the code and We want to do this using a simple factory implementation of the same go simple factory pattern and This means that We create a feed factory Which when given given a specific string like Twitter or WordPress Will return an instance of the application of the implementation to use so Do a checkout of the branch to feed me look into the code It already contains an implementation of the Twitter feed and You can think about what you need to change now to add the WordPress.com feed When someone pointed out that it's actually important that you actually use the git repo and not download the zip Because you won't be able to to switch branches If you You can find that one of the pages I created Where they were created they contain all the branches for today, and they also have a tutorial on how to To swap between them also my bad the WordPress out of occasion was a buck so I I typed something wrong, which This why you couldn't authenticate. So if you For though it's optional. I'm saying now you if you pull in the resources the latest version You should be able to authenticate with WordPress again. It's not required, but it does give you proper results Also some some small hints. There's a there's a class called plug-in in the code It it it explains what we're doing here So if you go to the plug-in class, you will see what we're doing and that's this is a good point to start working Just just with your co-worker Start working on it If you have questions, it doesn't matter our hesitations. Just raise your hand. We're here to do something interactive We're gonna work on this for like 15 to 20 minutes Okay, so I see you all busy. I hope it's busy with discussing the solution not the authentication still We'll move on just again the authentication is That the worst case is that if you have no Twitter Authentication You will get no results from Twitter and if you have no WordPress.com Authentication you will get random results from WordPress.com but still get results So you can still use the block for the for the further work. So that's why we added that API as well So we're moving on now to the To the next step. So in comes our client and It has a great idea It's very expensive to run all the updates of this server-side Render block all the time. So the client wants us to add caching to remove some of the bandwidth That is being used by all the time updating Now This is where The design patterns and the object oriented approach and depends injection start to become very Interesting. So first of all here's the business with crimes. We have we want to do some short Short-term caching five minutes just to avoid doing a lot of remote requests at the same time But five minutes is so short that it still seems to be updated in real time We want to implement this caching Without changing the feed implementation So we don't want to go into the Twitter feed and add caching and then go into the WordPress.com feed and add caching That's not how we want to work So we want to just leave the feed implementations as they are without any single line of code changed We also want to implement this caching Without changing the code that consumes the feed data because we might not even be aware where this code is used In the code base. So there might be several different places in the code where the feed is being used for rendering or whatever We we're not sure so we prefer to build something that does not require any changes This is where the decorator comes in the decorator is another pattern In this instance, we're using it for caching So a quick mention about what caching Represents in terms of a software engineering concept caching is something that we call a cross-cutting concern a Cross-cutting concern is something that is very difficult To put into one single place in your code base and just say okay. This is the corner where the caching is It is a cross-cutting concern because it it cuts through all the concerns of your code and is Oftentimes something that needs to be done to all sorts of places of your code That's what makes it so difficult To do it properly another type of Cross-cutting concern would be logging for example You don't look in one corner of your code when you add logging it's to lock the rest of the code to know What's going on in there? so these are cross-cutting concerns and When we want to add cross-cutting concerns in such a way that we are still Adhering to all the principles we want to adhere like the single responsibility principle or we want to keep all the concerns separated Then this is where the decorator comes in the decorator adds a New responsibility to an existing object without changing that of the object and it does this By wrapping the existing object and attaching its own code in the same way so it interjects between the producer of something and the consumer of that same thing and To show you how this would be displayed visually Let's imagine that this crook line, whatever it is Let's imagine that this is an interface. So the interface has a Specific shape and whatever we build to implement this interface. It needs to match this shape So when you have an interface normally tells you okay, you need this and this method And so any implementation also needs to implement this and this method Here's our interface. We have producing code. That means code That actually implements the interface and produces what the interface is meant to return And we have consuming code that uses whatever Implementation you've provided to to implement this interface and now when we're talking about a decorator It means that we split this up without changing them. We just split them up We put a decorator in place which Accepts an interface of the thing we want to decorate and the decorator implements the same interface as well So it acts as a as a middleman and neither the producer nor the consumer Have to change. They just never noticed that something else happened and Here's an example now of how this would look in code So we have a data interface And we have a renderer that accepts an implementation of this data phase a data interface and Fatches the data and returns it very simple code We have one implementation a remote data implementation of this data interface That does remote request when you when you call it's a get method And here you can see how the code is being used. We instantiate remote data We inject the remote data into the renderer and when we call the renderers when the method It will do this remote request So now imagine we want to add caching in there The straightforward forward approach would be to add the caching in here The problem now is though we needed to change our implementation Maybe that implementation was not even part of our code. Maybe we just pulled this in as the third-party dependency through composer Also now this remote data it does two things it does remote request and it caches the remote request so Out goes the single single responsibility principle So the way we want to do this is actually a different one We create a create a new object That only deals with the caching and that object is a decorator So that means the object accepts an implementation of our interface and It implements the interface as well We can see here that our remote data is clean again. It doesn't need to change just to add caching And here you can see how we use it We have our remote data implementation and we pass it into the cache data So we wrap the remote data with a cache data and the renderer can then still Accept this because it does not notice the difference between Direct remote data or cash direct cash remote data So if you call renderer render it still does the same thing and it never notices that we've introduced A middleman that added the caching This has a few Benefits one is that you can apply this to code that is not your own third-party code you pull in as dependencies which means that you can Consider a lot of the code that you create that is reusable as just Third-party code that is not meant to be changed which means it makes maintenance easier. It also means that When we add testing to our code Basically as long as we don't make changes to tested code We can always just assume it works and no don't need to bother with it. Don't need to Spend any thought on on it And the decorator Let's us add new functionality without Changing the code that was already tested that was known to work because as soon as we make a change There's no guarantee that that change doesn't break the existing code Here's a few tips of how and when to use the decorator As I said, it's especially useful for adding cross-cutting concerns, but that's not the only the only purpose But it's just it's a typical usage of it and The decorator also works very well when you have a central place where you decide What gets instantiated and how it gets injected into other objects? Because then you have one central place where you can inject this middleman and all the rest of your code will never notice the difference Here's next exercise So we want to add a caching layer Through a decorator this thoughts in the branch three cash is king So the feet object should be wrapped into a caching decorator so that we end up with a caching feet and We want to use short exploration transient caching for this So just use the WordPress get transient and set transit methods To to do the actual caching in this instance What time is available for this exercise? We have 20 minutes So again, it's mostly about discussing this and starting to figure out how to build these objects It's not It's no problem. If you don't manage to finish it The important part is the discussion and the thought process of how to go about this If you have written some code in the in the previous branch You can just switch to swap to this branch So you have to stash your results if you have the latest version of the resource repository It will show you one of the pages how to stash and then switch your branch Also in the last exercise we ask you to create a factory if you go to plug in Dutch php And to feed factory dot com dot com that php You will see the implementation that we wrote to do this So before you start with this exercise check check this branch out and once you've done it check out plug in Dutch php And feed factory so you can see what how we implemented the theory We discussed in the in the previous problem and then start on this one Just just a quick note again In case you need to break As our time is very short All always when we do exercises if you need to get a quick break if you need to go to the restroom So feel free to do it during the exercises and know that the completed code will still be there for you when you return So we don't have a specific time period reserved for break Okay We'll move on to the next step, but first of all I wanted to quickly show you What the caching feed should look like? so a Lot of you have already understood how the decorator works and could quickly build a first implementation of it So the important pieces of the team of the decorator is it implements the interface we want to wrap and it also accepts the actual Current implementation we want to wrap we want to add another behavior to and If we now scroll down We can see that Basically the interface is this get entries method and we still have this get get entries again get entries method, sorry about that and We add caching to it and if the cache misses We forward again entries call to the actual wrapped object instead that's the main main functioning principle of the decorator so Now If you want to see the solution in your own code, you can check out the branch three cache is king final But we will now move on We will now move on to our next business requirement So the client comes again comes in again and has a new idea On the production server We want to use object caching not trends in caching because the client now noticed that while trends in caching is not As good as it is hyped. So on the production server. We have something like red is Available some persistent object cache. So we want to use object caching instead Some requirements for for this new change The caching just should support different caching engines so Basically, we already noticed now that having one implementation is not enough We need to make the code more flexible and if you're already doing it then it's a good opportunity to abstract away Detail implementation of whatever caching engine we're using so we remain remain flexible in the future We also want to keep the duplicate logic to a minimum again and The consuming code should still remain completely unaware of what we did to change the caching So the exercise now is To keep the caching feed that you've built now you will probably have all version now if you check out the new branch Use this caching feed and inject a caching engine into the feed So this will show us that not only can we inject code and we can Use decorators, but we can also inject into decorators basically design patterns are meant to mix and match as needed you can Stack them you can wrap them in in each other you can use them in whatever creative ways you can think of So here we're using dependency injection to make our decorator more flexible The we should have an abstract caching engine We want to have multiple implementations and Then inject it into the caching feed decorator. You can check out the git branch for test me if you can Yet the name is a bit misleading because that was a different exercise at one point yeah, just use a branch for test me if you can and Try to create an abstract caching engine that you can inject Into the caching feed decorator 20 minutes for this and again if someone needs to use the restrooms or so does a good time to do so so we are continuing with the exercises a Quick note about the code we've built now if you check out the branch For test me if you can final you can see the implementation that we've built that was the end goal as we had As we had suggested it and Basically, we have created an abstract class caching engine which includes three methods a remember method a read method and write method With did it we we did it this way because an abstract class Can still be considered an interface? It's not an implementation because you cannot instantiate it But it already can come with default behavior that that you cannot That you cannot just skip and in this case the default behavior. We wanted to add is or Remember algorithm so instead of having just a read and write method and always needing to go through the entire steps of okay, let's do read if the read was If the read failed then we know the cache did it was a miss then we need to generate then we do a right etc So this entire algorithm if we only have read and write method in our caching engine We would need to do this algorithm in every single place where we use our caching and we wanted to avoid that That's why we have a remember method to abstract away this algorithm So we have it in one place And if we went need to we'd need if we need to do a change with that algorithm We can do that change in the one place and all the other places where we're using the caching We'll just use the new behavior and be good without any necessary changes Okay, I think we go to the slides yeah So the caching engine is then injected into our decorator Which means we can do this in one single location namely in the feed factory So the feed factory which already wraps or feed in a cashed feed can just provide the caching engine to the to the feed to the cashed feed decorator and This is this is all instantiated at the composition route and pass down the tree through dependency injection so the caching the caching engine if you go to the composition route We plug in so the caching engine is instantiated in one place and We inject it into the feed factory and the feed factory will inject it into our caching feed decorator So even if we might end up with a thousand places in our code that use caching We have one single location where we can decide which engine to use if we need to use another one It's one single change Okay, we can head back to the slides now So the last pattern we want to cover and we need to go a bit quicker now Because time is slowly running out Last pattern we want to cover is a strategy pattern so the strategy pattern allows you To abstract away an entire family of algorithms So you can easily switch them at runtime in whatever way you want without The rest of the code being aware of it This makes algorithms reusable and It also means that you can easily add new algorithms without any extensive changes in the rest of your code So here's an example of the strategy pattern. This looks a bit complicated now Basically, we have a user list that we want to sort based on several criteria We can sort them by phone by email and by name and as you can see depending on which criteria We want to use the algorithms are quite different between these and here's just a consuming code We load a CSV file. We add the users and then we can grab them by a sorted criteria Now to use the strategy pattern, we can basically do We can put the actual implementation of the algorithms into separate classes So here on the right side, you see the sort by name sort by email and sort by phone That all contain a compare method This is because we created an interface sort order that has a compare method to compare two users with each other and Now when we look at our user list and the function gets sorted by it's drastically simpler It's just a use sort. So that's a PHP Function to sort based on a custom callback that you pass to the function so we sort the user's array and we use our compare method as the callback and we even Injected Well, no, we didn't inject here, but we could inject so the criteria here is the one we get by the good sorted by Methods argument and we don't even know which one it is. We just know that it will be some algorithm to compare users and we just use it and When you look at the consuming code here You probably can't remember all of it, but I can attest that it's mostly unchanged The only thing that changed is that here our criteria is not some random string But it's an instance of the actual sorting criteria we want to use So that's the strategy pattern Which is also a very powerful pattern As you can see the code that does the actual sorting is very simple now and If you need to add a fourth or fifth Sorting criteria now. It's just a matter of Creating a new implementation of the sort order interface a few tips If you want to look at how to use the strategy pattern It's often if you see big switch statements or long if else chains that's often a good indicator that you can use a strategy pattern and You can also combine the strategy pattern with a Factory so that you don't oh, sorry so that you don't need to know the actual Class to use but can just defer this to a factory to instantiate it so we can have a random argument and instantiate the actual implementation through factory So the exercise then it's in branch five sorted out Introduce an ordered feed decorator Which should sort the entries based on abstract logic object So you can probably already guess that this is meant to apply the strategy pattern and Provide multiple sorting algorithms We in all case we used by publication date by author name and by content length to have a bit of a Variation in the algorithms, but feel free to be creative and use something else a Quick note the ordered feed decorator Does not mean that it replaces the cashed feed decorator Decorators are stackable you can just decorate a decorator which decorates another decorator and go on and on You just need to pay attention to the order in which you stack them. So here as we're dealing with caching You need to think about whether the caching order the or the ordering should come first and how to stack them in which order So we'll continue on to wrap up slowly First of all the branch to see the final code is six. That's all folks So you can check out that branch to see what we finally come and came up with to build this good work log He has no review of the his view of the ordered feed the decorator that now includes or our strategy pattern so in the constructor in the constructor you can see that we are injecting a sorting strategy implementation and If you we look at the get entries implementation further down So we're still retrieved to get entries from the feed that we're wrapping But then we order its entries and return the ordered entries and in this order entries method We can see that we're using use sort to use whatever strategy That was injected and call this strategies compare pattern is to call back for sorting So this does sort Our entries but that's completely in your how they are being sorted. That's a different object a different responsibility Just as a quick example Hit up the by author name or something some strategy Yeah, just hit enter. Okay. No, that was not it. But yeah, that's also a very nice Yes No, it's not sort by it's it starts by by author name by Because yeah, there's this one. Yeah Okay, so here's one example Basically We do an implementation of the interface of the sorting strategy interface and this interface Just says that we need to have a compare method that compares to feed entries and returns an in value The usual way sorting algorithms and PHP are being used is that they return less than equal or greater than zero based on whether the first and entry is is Smaller equal or greater than the second one respectively In this case to implement this we use the get author name from both feed entries To make sure that we have a fair fight. We only use lowercase letters for both of them and We use the spaceship operator here That basically returns this integer value that we need and this is just one simple Implementation of a strategy and we can have whatever creative ways we need to sort them Okay, let's get back to the slides so Let's move on from here. I Before we close off. I wanted to quickly Show you an optional homework exercise you can do Another pattern that we that we haven't discussed yet, which is also very interesting and also nicely fits into the plug-in here But we won't show you the finished implementation. This is something you should figure out on yourself at home So the abstract factory is basically still a step beyond the abstraction level that a simple factory provides the abstract factory abstracts away factories so Which sounds like quite a mouthful, but what that what that means is that? You have an object that can create instantiate other objects and It doesn't even Depend itself on any specific way of instantiating these objects. This can be extended Even by third-party code So to better show you what this means Let's assume Gutenberg was built in a clean PHP and would contain an abstract block factory that has separate factories for each family of blocks So we have simple factories here and the abstract factory abstracts away the fact that they are multiple ones and When Gutenberg requests a block it will just request it from the abstract block factory and whoever is responsible will retrieve the correct in implementation and The big advantage of this is that We can create a plug-in that hooks into the abstract block factory and registers an additional factory Which can instantiate new blocks that were not part of the core Gutenberg experience and all of this works Without changing a single line of code in the Gutenberg plug-in so this makes it immediately extensible and third-party code can easily add factories to add instantiations of implementations So as a home exercise, please think about how you could extend the code so that another plug-in could add could add a third feed Implementation to this social mentions block Yeah, okay, that's the slide Yeah, you need to think about Providing some form of registration mechanism that the external plug-in can hook into it to get access to this abstract factory that's the difficult part about this and Yeah, you can Google about how the abstract factory is built But I think that by now what you've seen will probably make it very straightforward of what? The actual implementation of an abstract factory will look like the key takeaways of this session, hopefully is that Design patterns are not copy-paste snippets design patterns are ways of Thinking about a solution that has shown to be Preferable in long-term and applying this and applying it in different contexts These design patterns can take All sorts of different shapes and forms if you use them in in real life They not always are exactly like the example code you see in the academic books, but that doesn't mean That they are not these patterns. It's just about a Conceptual way of solving a specific problem When you will go through the code that we've provided to you There's other parts of the code that abstract away all the the Gutenberg block stuff There's you already started with quite a lot of code And if you go through this in detail, you will see that there's all sorts of other Instanciations of these patterns you will find additional factories you will find additional decorators And I think that I managed to always denote in the file header dog blocks of each class When they represent a given design pattern, so so you will find more examples of them inside of the example code Another key takeaway should be that dependency injection lets you defer decisions So whenever you can defer the decision You can be much lazier and not Care with all the technical details that would normally need to be solved and just Use a concept Don't use a given implementation. Just use a concept and trust that At one point we will solve the issue of knowing which implementation to use But we always want to defer this decision The third decisions mean that when the decision changes our code doesn't need to change because it isn't didn't rely on that decision in the first place And there's a third take away When when you apply these design patterns and when you apply Dependency injection these are all building blocks and you can combine them you can mix and match them You can combine a decorator with a factory and inject and Wrap and whatever and there's no limit to what you can build with these basic building blocks finally if this has Proven to be interesting to you if this has shown you that design patterns can be a useful tool for you Then know that there are probably at least 80 more of them to discover This was only a small Subset of the available patterns that are documented today We all fortunately needed to limit to the scope of this workshop, but if you Google about design patterns if you Look into books about design patterns you will find a lot of other patterns like this and Maybe now that you've seen how to apply them in real life This will help you get through the academic Mumbo jumbo that comes with the design pattern explanations and you can more easily See how you can use them for your problems and how how you can apply them in your actual Daily life and make it easier Yeah, David is there anything else you want to add So, thank you all for participating in the workshop feel free to also ask questions If you have them you can contact both of us on Twitter We're also available on slack We're always happy to help we we really care about Helping make the general code better because we also need to deal with it every day please help us all together make our own environment better and Also a big. Thank you to the TAs. We did a fantastic job of Helping everyone get up to speed and get moving Thank you


So today we're going to answer a question that we often get which is why is my IELTS reading score not increasing? And there are four key things that we're going to talk about today to explain why students no matter how much work they do They still struggle to increase their reading score. So when students email us and tell us My score is not improving. They're often frustrated for one of two reasons Normally, they say that they have done Some kind of reading course that has lots of strategies in them So they'll say I have completed this course or I am following these strategies and My score is not increasing also. Commonly we get Students who say I have done all of the practice tests that I can find I've done all of the Cambridge books all of the online tests and my score is still not increasing And the problem is is that if you are just relying on doing lots of practice tests This is not going to help you increase your score at all. In fact, it can lower your score Because if you're doing the wrong things Practicing doing the wrong things is going to lead to you getting worse not better Also, many students have a misconception about Learning on a course or learning strategies and thinking that these will automatically increase their score In fact, if you do it wrong, it will decrease your score So in order to solve this problem, we teach our students four simple things So what we do is we explain to them that the strategy that we're going to use is Kind of like a car. So I know that This is a beautiful drawing of a car. I know that my my drawing is amazing So thank you so much for for complimenting me in the comments on that, but a car has four tires Okay, so it doesn't matter how good your car is you could have a brand new Tesla worth a hundred thousand dollars if one of your tires is busted that car is completely useless These four things over here Represent the four tires and if one of these things is missing Then it doesn't matter how many practice tests you do. It doesn't matter how many courses you do It doesn't matter what you do You will not increase your reading score unless you do all four of these things So let's talk about what these four things are. So the first thing you need is you need a strategy for each Question Type so for example, you might have a true false not given question or you might have a matching headings question and these two questions are testing different sub skills and Require a very different strategy for each of these two different types of questions now the problem is is that many students will learn a strategy and Then go and do a practice test or some practice questions And then what they'll say is your strategy does not work Well, that is a problem with your overall approach not with the strategy Because your goal is not to look at the strategy once it is to master the strategy So the key thing that you need to do at this stage is master The strategy So what does master mean master means that you could teach that strategy to someone else If someone asked you what is the strategy for true false not given you wouldn't have to look at your notes You wouldn't have to check anything you would be able to tell them Oh step one you do this step two you do this step three you do this step four you do this and you can tell Somewhat automatically what to do in other words on test day You were able to look at a true false not given question or a matching headings question or a multiple choice question and Do this strategy automatically without even thinking about it The problem is is that if you look at a strategy, but you haven't really mastered it that strategy is useless Your wheel here your tire is broken. So that brings us on to the second part, which is practice tests So what a lot of students believe is if they do more practice tests their score will increase Well, this is not true. So what you need to do is is approach practice tests a little bit differently Your goal here first is just to have a first goal, which is to master The strategies so this means that you take a step-by-step strategy and You take some practice questions and you take as long as you want time does not matter here What matters is you mastering the step-by-step strategy. So if it takes you One and a half hours or two hours or three hours just to do one practice test. That is absolutely fine The mistake that a lot of students make is that they look at a strategy and then they do a practice test under exam conditions They don't get the score that they need and then they get very frustrated And they blame the strategy or they blame themselves and they start to think I'm not good enough and I'm going to fail this test I hate this test And then they give up you don't need to feel that way So first of all you take the strategy and you apply it to practice tests and take as much time as you want Because you're just trying to master that strategy take as much time as you want Think about what you're doing and then once you are comfortable using the strategies You can use the practice tests for goal number two Goal number two is do it under exam conditions because you're just trying to find out your weakness So you're going to do a weakness analysis In other words, you're looking at your mistakes What mistakes are you making and are there any patterns to these? So that takes us on to the third thing here, which is Mistakes or weakness Analysis so you're going to think deeply about each mistake and the reason why you're doing this is you are trying to establish any Patterns, are there any common reasons why you are getting a low score? So for example, if we have a look over here at our mistakes Let's say you get ten questions wrong and eight of them are spelling So you got eight out of ten wrong just because of spelling errors Or you might find that you got confused about the strategy for a particular question or You might have worked out that you couldn't find the correct answer because you didn't understand some of the words It was a vocabulary issue or it could be a skills issue For example, you find it difficult to find the location of the correct word That would be a scanning issue or you find it very difficult to understand general meaning That would be a skimming issue or it could be a particular type of question For example, every time you do a true false not given question You really struggle with that particular type of question or every time you do multiple choice questions You really struggle with that particular type of question and if you never do this Again, you will have a busted tire and it doesn't matter how good everything else is It doesn't matter how good of a car you have if you have one busted tire You are not going anywhere that car is completely useless. You will not go anywhere Your score will not increase until you follow this system But that is not the end of it once we understand what our weaknesses are what our common mistakes are Let's say you look and you see that vocabulary is an issue and True false not given questions are an issue. You cannot just stop there You wouldn't believe the number of students that we work with even we work with one-on-one and we tell them the only reason why your reading score is not increasing is because of vocabulary and This particular type of question and then they do nothing They go and do the test and then they fail. You don't want to be one of these students What you want to do next is work on your weak Areas so we want to take our weak area and we want to convert that weak area into a strength So for example, we want to improve our vocabulary or improve our ability to answer true false not given questions So we're acting more like a sniper than with a shotgun. It's a sniper approach We're not focusing on everything We're just focusing on one or two weaknesses But you must use these four things and you must use them in order and then that brings us on to our last part Whoops, which is all about time So every time I explain this to a student what the student will normally say is I don't have time to do all of this Chris, can you not just give me some quick tips and that's going to really increase my score? No, because there are no quick tips that are going to increase your score so I had a recent student a VIP student and she was a pharmacist All right. So I said imagine I come into your pharmacy with a headache. So this is me With my headache I'm not very happy because I've got a headache and I say can you give me some drugs? Can you give me some medicine to cure my headache and she is a great pharmacist? So she gives me some paracetamol to improve my headache Imagine I come back five minutes later and say your paracetamol your medicine doesn't work because I still Have a headache what would you say and she said I would think that you were being very unreasonable and very difficult Yes Certain things take time. All right. So if you have two students imagine we have two students and one student Let's say today is June 1st and they book their test for July 1st And they want to get everything done as quickly as possible in 30 days then we have another student so today is June 1st and Instead of thinking about booking the test what they do is they just focus on The process They just focus on doing step one and then step two and then step three and then step four This student is going to get the scores They need in the quickest possible time This student will probably fail because they're trying to do everything as quickly as possible Like to go back to our car analogy This person if they have a flat tire it is probably going to take them, you know like 30 minutes To change the tire, but if they want to get everything done in five minutes Then their car is going nowhere and they're just going to be very very frustrated This is what happens with students who fail the test over and over and over again Because they're trying to do everything as quickly as possible Instead of doing things the right way if you follow this system You are going to see great results But if you miss one of these steps and you don't master the strategies you don't Find out what your weaknesses are and you don't work on your weaknesses. Then you are going to fail. So just to recap Get some strategies that actually work that have been proven to work and master them so that you can use them automatically On the test master means that you could teach someone what those strategies are without looking at any notes then do a weakness analysis on your practice tests and then Work on those weaknesses find out what why you are getting a low score and then turn those weaknesses into strength


Sound of the final Hobbit film, The Battle of the Five Armies, and I'm happy to say it's the best of the three. I enjoyed Desolation of Smog for what it was, which is just a cheap ride. There is no real substance to be found. I thought the last 30 minutes drug on with no real conclusion in sight. This new one starts up, the dragon's eliminated almost instantly. I knew it would be done within 10 minutes. I was worried what was going to follow. Fortunately it was a very good script. It was very fun, there was a ton of action, and now Legolas is a full on video game character.   We'll call it Assassin's Creed. Outside of Legolas there is a lot to like too, but he is my favorite part of these films, which is amazing because he has zero personality in the Hobbit trilogy. Unlike the Lord of the Rings, there's no charisma, there's no wittiness, he's just a stone cold badass. Martin Freeman once more playing Bilbo is spot on, then you have the great Ian McKellen playing Gandalf, Thorin gets a little bit more range as he gets engulfed with the dragon sickness, Kate Blanchett, Christopher Lee and Hugo Weaving just make it feel like a complete series tying into the Lord of the Rings. The biggest criticism is that this should have been two movies at the most, I mean it's been said to death, but it needs to be repeated because Act 2 really is just a bridge film that didn't need a bridge at all. The bridge was there at part one, just jump right to two if you need to extend this thing out past one three hour movie. I am happy to say that unlike the Star Wars prequels, I will gladly watch these with my kids someday in the Order Jackson and Tolkien wanted, I will start with the Hobbit and go to Lord of the Rings and that's for multiple reasons. One, this isn't near as threatening of a film, it's shot mostly in the daylight, I don't even know if there is any dark scenes in the third act. Two, the CGI is fine but it's well overdone and it's a doubled what Lord of the Rings has easily. Lord of the Rings holds up much better because it uses a lot of practical effects, costumes, makeup, on top of CGI.  There are some really cool one on one battles and that final one with Thorin and that albino fucker that keeps following him is a sight to see. There's some really good drama, some of it's very forced, like the love story that nobody asked for with the female Legolas, but I had a great time here and I can easily rewatch this Hobbit series, is it anywhere near Lord of the Rings? I don't think so, I am going to feud Lord of the Rings versus the Hobbit, both trilogies on movie feuds and I'm doing the Hobbit trilogy versus the Star Wars prequel trilogy, so stick around for those, they're going to happen in a couple weeks. I'm going to give the Hobbit the battle of the five armies and nine out of ten. I really enjoyed it, regardless of some sketchy CGI from time to time, the pacing is very good, it's fast for once, especially for a Jackson film, it's also the shortest of the entire suite of films he's done. Let's hear from you now, post a comment, let me know where this stacks up in the Jackson universe for you, is this your favorite, least favorite, somewhere in the middle? Let me know, subscribe to Feud Nation for all the latest rants, car side reviews, and movie feuds of course. That's probably the last big car side review for the year, what's on the horizon? Jupiter ascending? That's going to be a mess, I'm calling it right now. I hope I'm wrong, but Chelsea's could use a hit.


When they exhumed Medgar Evers' body in 1993, 30 years after he was shot by a clansman on his driveway, his body was in pristine shape, pristine condition. This is something for a Muslim to think about. God will be merciful even if we don't want him to be. It's interesting, the Prophet said that the flesh of martyrs does not decompose, that God, he preserves them, they're incorruptible. You go to places in the world that, you know, like saints are buried, where they're not actually buried, they're in open air tombs, they're not decomposing. And that's something for the Muslim to think about.


Say when oh when all right. Hi guys. My name is Andy apes. I'm a senior software developer Adele The noise me maker in chief comment if you want clarifications Bring me later. So What this session is about the thing will actually advance about that is Basically around the deployment mechanism So one of the problems that a Little background so I work on a product called crowbar the little crazy bunny at the bottom Which is basically a deployment system for open stack. This there were a couple of sessions There are a few others that talk specifically about crowbar, but for the purpose of Of what we're talking about here. It's basically a deployment system for Open stack and any other large distributed environments one of the Things that's always annoying is that this thing runs around One of the problems with open stack is around testing a large distributed environment. It's it's Not sufficient to do a single node deployment and assume that it's actually gonna work when you deploy it in a real Multi-node bare metal environment and we've seen quite a few bugs in open stack that were revealed only when folks Actually went and deployed on a multi-node network Real honest-to-get environment as opposed to what Dev stack kind of does where you deploy everything on one stack and hope for the best so What does it actually take to deploy a to test open stack for real and what is it that you want to achieve? Well, you want the deployment to be reproducible and predictable. You don't want every time you deploy it for it to be a little different You want it to look like your production environment. You don't want it to be simulated So for example, if you deploy Swift and you lose use loop devices and simulate the presence of multiple disks available Well your deployment is not going to behave the same in the test environment as it's going to be on a real server with 20 disks You want to be able to deploy the code you want to deploy you don't want to be dependent on oh There's a new maintenance release that just came out Friday and it all of a sudden has New bits new open stack bits that's happened last Friday It was a new maintenance release for sx and if you are gonna go deploy a new system that go hits the internet You're gonna get those bits instead of the bits you were expecting because well, there's new better bits So you want to be able to control what it is that you actually want to deploy in your environment either for testing or for production One of the Things about open stack that's actually kind of cool is that you can customize it you can go create your own Scheduler you can go add your own drivers Well, you want to be able to deploy them in your test environment and make sure it works with whatever bits of open stack You deployed so all those things are currently Somewhat less than optimal in the testing and deploying solutions that are out there so that's pretty much the drivers for this session So some of the problems is how many nodes are we deploying a deploying on one or are you actually deploying a real? Production like environment are you? Deploying one static configuration, or I actually trying to modify the configuration it keeps ruining my punch line It was Well, I will speak faster apparently because I need to speak faster Are you actually configure applying all the diverse configurations that opens that gives you and testing them like you will Actually be using in production, or are you just trying the one true and only? Default configuration that whatever deployment system you're using Quick question how many folks actually deploy and operate open stack You've have you ever hit problems of I don't have the right dependency on the right Python module right packages I'm missing this bit and everything comes crashing down in a fiery ball of hell so have you ever tried to deploy in a new system that you've never deployed before open stack on to and Well your connectivity or the repo you were hitting didn't write didn't have the right dependencies And all of a sudden nothing works for you anymore and all your ci infrastructure is coming bloody red These are some of the issues that basically this solution what I'm Get to in a second basically tries to to solve And that does not include me being friends with Powerpoint which is not very happy with me. So some of the other solutions Some of the other solutions that are out there. There's obviously many different solutions for crowbar. They are one of the Most popular one is Dev stack anvil or Dev stack py is not a one and juju is the other not one each one of them tries to It's not a new problem. Every everybody who's been deploying and testing open stack has hit these types of problems I want to go into details into one of them into all of them if you're interested We can chat about them later, but basically there's still Shortcomings and obviously my solution is the best so so one of the first public Testing efforts for open stack was the canonical folks who've been doing a really good job around Again, it's wrong That's what happens when you put engineers to use bar points Sorry about that So the canonical guys have been doing a great job testing their packages They basically go and get the latest code their package and they deploy it in a test environment They test it and they publish test packages One of the question marks which kind of ruined my thing was do you really need to package?  There are some problematic Areas in open stack like attaching volumes once in a while Do you really need to go for the whole cycle? You really need to publish packages just for you to be able to test that Those customization and your deployment will work What would be cool is to actually skip that packaging it would be cool for you to be able to say here's my code Put it in your canonical get repository or wherever you use your production code Put all your configs that you're planning on using. I love PowerPoint. Sorry about that Get everything that you actually care about Stage in your test or pre-prod production and see if it's gonna work Right What's missing from the previous? Solutions from the current State of the world It's not that easy to deploy multi-node each one of the solutions from the prior slides require you to go and Pailer the nodes individually if it's death stack in the go need to need to go create local personality Local RC basically go and configure the node give it its own IP address make sure the right It ties to the right interfaces on that particular node It's gonna keep ruining my Same goes with anvil same goes with juju There's a lot of manual tailoring that you need when you actually want to go and deploy a multi-node environment Same goes for multiple configs if you want to tweak the configuration for example switching the networking mode from flat Http to vlan. There's a lot of oh, so now I need to make sure that The base operating system has the right net we can configure it on it I now need to go and tailor the open stack config and make sure it actually is aware of what's Configured on the node and make sure it ties in correctly all the fun stuff that you have when you try to Deploy any kind of more than single node open stack deployment and none of the current Deployment solutions base address to any real degree the concept of a custom code that you can easily pull from your own repo It seems so simple marketing guys do it So what's pull from source all about so starting from? A production employment system that is crowbar that basically knows how to I'll quickly recap it knows how to take a system configure its hardware deploy the operating system on it Configure the base networking for the operating system and tie it into a management network then deploy from packages the Standard bits for open stack that you're interested in Customize the network based on the components on each node So if it's a swift node that might need both a storage network and an admin network and potentially a public-facing network If it's the proxy the swift proxy node or if it's Nova based on the networking mode You're using it will need to create the appropriate networking Do you need to create bridges so the VMs have something to connect to do you need to create appropriate V lines and so And then lay it down open stack and tie it into the various pieces so that's that's a starting point what this feature this set of tweaks to Crowbar achieve is basically let you do all that but all without the packages What's missing some of the things that from crowbar what? And how does it tie into the ecosystem of of open stack so? By the way, feel free to interrupt me or stop if what I'm talking about makes no sense One of the things that packages do for you and do it very well is manage dependencies nothing lives alone, especially not in the world of open source and At last count when I counted packages and Python modules. They were about a couple hundreds that given Nova Node will actually need to pull down and install in order for Nova to actually work What do you do if all you got is the source? Let me see so one of the things that Dev stack which Gates trunk meaning tests every bit that goes into open stack That's very nicely is maintain a list of what prerequisite packages are required at least for a couple of distributions Not for all not for you all the open stack Linux distributions the other thing That's required is what other Python modules do you need on the system? if we want to use Crowbar or any other system to be able to get to a point where we can Trunk I'm sorry gate to trunk on it on tests run using this deployment system We don't want developers to have to go and update things in multiple places, right? If you need to pull in a new dependency, you don't want to have to go and modify things and Your deployment environment you want to be able to just touch the source code Well, so in open stack currently every project maintains its pip requires Because do people know what I talk about I know you guys do show hands Kind of okay, maybe So pip requires is basically at the set of Python modules that are deployed on a node when Before Nova is deployed and before and before you go and run the unit tests on the code to make sure it for it works So if any dependencies are broken if something if a version If you need to update a version of a module that you depend on and it hasn't been updated that Change that commit that changed open stack is not going to be accepted because tests are going to fail until you go and fix the list of dependencies in the project and at that point you will that's basically the source of truth around what I don't pass on modules this particular module requires Okay, I should have prefaced this and say this was meant for slightly more developer-oriented crowd Other things that you might want to affect on your testing environment are how do you want Nova to be configured? It's extremely flexible. How do you manage the configuration for a multi node deployment? In a sane way and the crowbar environment You basically have a nice GUI that you can play with but everything could do in the GUI You can actually describe in a simple JSON file that you can manage via your Favorite CLI's and you can check in into source control So you have a prescribed set of configurations that you can step through and vary as you want So you can make sure that it doesn't work in just one environment, but it works for everything I'm gonna skip the rest of the things because they're probably not that interesting So what's the process? You take all the bits we we talked about right you take The requirements the list of requirements you have you take the open source bed at the open stack beds you Basically go and package them into a self-contained archive again. This is the crowbar approach That gives you the reproducibility and predictability Nothing depends on things from the outside world unless you choose to you have the option of basically archiving everything You install the admin nodes that basically serves as the controller for the your environment test of production and it basically has a Get server based on it at low server It has a PYPI repository mirror that you can basically get everything all the dependencies Python dependencies from and it has an app repo on it that again basically gets lets you install the environment from a known tested to be good self-consistent set of Bits without having to go to the to the webs if you don't want to again This is engineers doing builds Okay, no Trying to make builds work So you first deploy the admin node and get that running and at that point you can deploy any number of notes So to show you that it's not just vein words It's actually That's the wrong window excuse the windows so Realizing how good open stack conferences What a good reputation open stack conferences have around Wi-Fi accessibility. I'm not gonna try to build Do a build right now because it downloads about 200 megs of stuff Rather, this is a build I ran Today's a Friday So one of the Challenges Often is to figure out what do you need where do you get the information of what you need? And how do you package it in an environment that you can then use for your testing? So the log file that we're looking here is basically Let me start with a little earlier this is extremely verbose by the way, this was so you'd believe that and if you are Enthusiasts You're welcome to read it. It'd be nice if I could see what I'm typing Sorry that so basically this is oh, I should mention that our team here actually was very Contributed a bunch of the code most of the code to basically figuring out dependencies and bringing things down So this this is basically a log file of building the ISO that will contain All your dependencies and will basically use be used to install your environment The bunch we're on the screen right now is basically going and fetching the depend the Distribution based dependencies not everything is open source. You don't want necessarily to build everything from scratch So we still rely on packaged bits for things that are outside of open stack things like python setup tools and Random a large collection of bits How large So what's crawled About 3000 random odd packages The other part and again, I Think I'm going to details that is probably not a very interesting to the audience.  That's basically That's basically the holy grail. We can have a very short test codes deploy test cycle where You don't have to worry about any externalities that you don't want to choose to care about Let me pause here and see if there are questions or So I Don't know if you're familiar with crowbar at all. I didn't want to go make a discussion about crowbar Because the intent was to keep it a lot more So if I want to deploy a Nova environment Ignoring for a second all the other other pretty prerequisites that Nova requires no requires a database a keystone Maybe you want to install dashboard. We're basically the way crowbar manages this all is by Managing proposals where you basically say here are my nodes And here's the role that I wanted to play in the cluster in the cluster that I'm deploying So for Nova, you would need a controller You'd need a few computes and potentially you want to install a no volume the way you'd manage it in In a test environment or when if you are CLI type of a person you Say for example, I don't know the text visible. Sorry So, you know, it's live because it's obviously barfing left right and center. So I'll skip the CLI for too many things but big Basically You'd basically get a JSON file that lists all the parameters that you want. This basically lists the default one Right, so the same assignment of here are my nodes one of the things that you'd notice. I didn't have to change anything currently in this crowbar deployment. I basically have three nodes if I Would To commands create me a default proposal and apply it I can basically pick off a deployment of Nova on these previous happened to be VMs on my laptop But those could very easily be physical servers. So it's very easy to script The workflow would be where you'd create Either do what I just did where you create the default and then apply it or you can have a few pre-canned configs with the various parameters that you'd want to customize for your environment things like networking mode Does that I'll just use the GUI it's easier to look at Okay, so so basically crowbar Manages a life cycle of nodes nodes will boot up the HCP and sit and boot into a live image where they basically sit and wait to be told what to do and Crowbar basically orchestrates deployments on those nodes by triggering currently only chef Executions on those nodes when something needs to happen on them. So once you put up the node it will sit there until You commit a proposal that gives that machine a personality or purpose to be to do more than just wait there once that happens it will Crowbar will basically lay down the operating system by either kick-starting the seeds depending if it's read head over to and once it Boots up again and calls into crowbar and says hey, I'm here and ready. What do you want me to do? crowbar will configure chef for that node and trigger a chef client execution on that node tying the different nodes together and tying into the specifics of the network so At crowbar will assign at an IP address make sure it's on the right subnets if there are VLANs or bonding or any kind of Networking configuration that needs to occur it will be performed before you try to bring up the the open stack component that you're deploying on that node and So if you need to deploy multiple proposals right multiple components So if we look for a second at the various components of opens tag that you need To have a functional cluster you'd need to deploy my sequel because again, you're trying to test like you'll test in production You don't want to run against sequel like you want to run against a real database server Sorry, you'd want to deploy keystone you'd want potentially to deploy swift if you that's part of your environment or just glance you can basically queue up all those things and tell crowbar here's what I want and as Components come online crowbar is aware of the dependencies between them. So for example, if I want to deploy No, but I can either choose one of the the default of what my sequel cluster or one Operate against what keystone instance do I want to operate what glance cluster? I want to operate on gets pre-populated assuming they were already created. So as you if it's not it says Oh, I got none and it will wait until one becomes available So basically there's in many scenarios. You have this like chicken and egg Polling how do I know things already ready crowbar basically orchestrates the deployment make sure that things get deployed when they're ready Sorry, you'd have to speak up a bit Do you mean security? So the question is around IP sex security associations so at this point we basically make sure that authorized SS age authorized keys are available and But we don't we don't deal with IP sec. We haven't heard customers actually asking for it Do you have other specific mechanisms you're thinking about other than SSH? Yeah, so basically crow will ensure that there's a secure key generator for the root user and it this it's distributed to the nodes So you can actually and install this an authorized key so you can actually communicate between all the nodes Sure, we actually So crowbar can deploy swift it's actually one might have a warm spot in my heart for swift because I wrote that Any particular questions or So I don't want to dwell too much into Swift and I don't know if it's a little out of the scope of here One of the challenges with Swift is that it actually it's very smart about discs You want to be able in order to test Swift you need to have enough devices to make Available to Swift so it can create replicas or multi devices and on multiple nodes Otherwise the whole purpose of Swift is kind of defeated in a testing environment especially The way Dev Stack is set up currently to test Swift is by creating loop devices or basically taking files and pretending there are discs and Making Swift work against them. It causes Let's say like this. You don't want to run performance tests on that type of setup because You kind of defeat the whole purpose of having many discs and many spindles available and getting much better performance You'd want to be able to deploy in real environment with taking advantage of all the discs you have In your environment to get realistic performance numbers So yes, that's actually one of the things we've we've Targeting Krober to do is basically be able to do real performance testing on the actual hardware with Lots and lots of spindles on the same server Sorry, there's a light right right above you, so I didn't see you there So so you're asking a few questions. Let me see if I captured them. So the first question was is that a particular Bar clamp or not or and how does it relate to the shift cookbooks? So there is a new bar clamp that basically will deploy get in a server configuration. There's no real get server Basically, you can denote one of the nodes on in the cloud environment to be your get Repository that all the other nodes pull from So there's one new bar claim to deploy from source basically all the other bar clamps were modified to pull from that To find that get repo in the environment pull from it to the source and deploy it locally on the node so and That basically is modification of the chef chef cookbooks that were already in the other bar clamps. Does that answer your question? Any other questions So apparently I thought this is all on github already But apparently I was a little glitch This will very soon be on github the code is but there were some branching structure issues, so I want I Won't dwell on that I Think that's if there are no other questions This slides with Up-to-date links to where the information is available will actually be uploaded to the slide share for the conference and You're more than welcome to play with it would love to hear feedback That said I've been told that I need to say that we're hiring so if your developers product managers are interested in open stack Stop by the Dell booth and people would love to talk to you That's about it. Thank you much