Jeff Smith - Pretty State Machine | Code BEAM SF 19

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right so this talk started here this is the gym stadium documentation as well as from the standard library in the design guide this was pretty not about six months ago it's got coffee stains wrinkles notes all kinds of stuff but this talk is basically this convinced into hopefully 40 minutes now to share with you kind of some of the some of the challenges I had learning this behavior it's different from gen surfer we have meet Carl Sagan fans in the room okay the movie contact this is sort of how I felt after I read all this so my premise is if you want to do reeling in the lips are well you have to think like a telecom switch so again my name's Jess Smith finally on Twitter electric shaman this is me my wife tried to take me to the beach one time and I'm a rock town so naturally I just went to look at the rocks alright so again the objective of my talk here is is to encourage I think there's been there's been some pushback maybe for people about you know we've done gen server so much that like these things are burned into our neural pathways we get we we get to the documentation for gen C I'm thinking I know I've got a state machine here and we look at it more like oh my god like that's there's there's about five different things you have to have open in your browser to really bring this whole thing together and I'll share those links with you at the end but at the very least I just hope it will encourage you to kind of get over that hump you know complexity there to really understand the power of this behavior so an interesting thing to keep in mind is that even though we have all this power the performance with James didn't is actually on par with gen server and this was this for those that don't know this behavior was released early eighteen and then there is a if you are using gin FSM there is an upgrade path and that's in the documentation one way to put it is it's more flexible and more abstract engine server that's one way to put it and since I I primarily rate elixir my day job like a lot of the code there's not too much code but some of it it's all an elixir and so there's a rapper out there for a lizard called gin state machine really great library there's a lot of great documentation in its own right like I said there's about five or six different things they're gonna you're gonna want to have open as you're learning this behavior and I would argue that the gem state machine documentation even though it's an elixir if you're an early developer it does provide some additional context telephone I didn't use gin FSM before I learned this behavior so that may explain why am i running away streaming if you have pre-existing sort of mental model alright so just so the beginners this is so the beginners don't get lost this is kind of intermediate talk and I'm not going to go through all of the how-to stuff on on gin Stadium but I will at least give you some high level concepts to kind of help with the rest of the presentation all right so let's start with state so how many people use gen server like regularly okay yeah everybody so we're used to thinking of state is like where we put stuff right you want to process to hold on to stuff and stay in the state but in this context what we're talking about is we have a state machine it's just our state so this is like an atom you can you can do today I just want you to remember that when I say state I'm talking about the actual what you're used to thinking of gen server state he's now called data it's very descriptive but that's where you might put you know if you're modeling likes a door lock that's where you might put the code or stuff that you're used to putting in gender or state it's probably going to be in data the event in this case whenever messages come in through casts or calls we're talking about events in this context so it's it's the same thing cast and coal that's how you interact with Jen's they know but the messages in this case were called events anyone hear me okay yeah here we go okay so the action this is the this is where the power is really evident an action engine state M is something you want the behavior to do for you when you leave one of the call Linux and the really cool thing about this oh sorry I skipped something when we're talking about events I want to make sure that we see the parameters so I'm wandering the way the interesting thing is like forecast and info and call like that's going to come in as the type and then your content you can see if you press to the digital economy on a door lock that that's your content so again action is a really powerful thing in genesee them there is a way that you can you can do multiple actions which is not something you can do with jen-jen server you typically engine server you would do those things yourself before you left the callback but would Jenna state em you can actually give it basically a list of little patterns of it expects do multiple things whenever the callback exits okay so an example might be you can do a reply like you could need to reply to multiple callers if you wanted to you can set a timeout which I'll talk about those in a little bit you can also insert an event into the queue which is something you can't do directly in djenne server and so in this example you can see that the third tuple down I am saying the next event is going to be a caste and emulating the button five so being able to do multiple actions really interesting and powerful thing you can do and to get started with which in genesis sorry Jen stay down you know it looks just like Jen sir you have basically the same sort of start link situation and then the Annette call back the only thing that's different here is the state and then we provide the data that I talked about and this is a special process just like Jen server and OTP and so you get all the benefits of tracing and debugging and things like that so the first concept is something called comb at home and since this is kind of a meta talk like I you know I like to try and pull the metaphors and ways to explain things it's basically choose-your-own-adventure so you have two options so it's not you know all that much fun but the mission is the same what do we want to do we want to handle all the possible combinations of events Penn State I really the callback mode helps you define like how your code ends up getting organized as we'll see here the default callback mode called handle event function you can think of this like the event centered approach the sort of organizing logic is first by event and then by state and this is the default callback mode so here's an example handle event takes four parameters first being the event type second parameter flip being the content current state is the third message so you can see we're in the off state right now and then four parameters being data and we're just telling the Machine here I want you to transition to the on state and increment whatever's in data by one the next option is called state functions this is the state senator probe so your code ends up being organized more around the state first and then the event you read the docs for this particular callback mode what you're going to see is something that says one callback function per state and just like gen server we're not talking about one function head we're talking about you know one function name that could be you could have pattern matching you know in fifteen different versions of it but it says state named three in the specs for this guy and that threw me off is like well I thought I had four parameters and what's the state name right well as it turns out it's the name of the function like they actually use the name of the function for the current state that you're in and so this is the same example that I showed for handle event function but now in the state functions call that mode and the way that you would tell you would tell your behavior which one to use is just another function and so although if you're using gen state machine wrapper for a lick sir you can provide it with the the use macro as well so same behavior different callbacks it's to throw an adventure you can also switch between these guys in upgrade and downgrade which I have not had the courage to do yet or the need but there there is a pathway there for you to upgrade or to transition between the different states if you're doing if you want to do that so say that you have you know 15 different callbacks for one particular state let's say that you notice that in all of these callbacks you have the the same kind of initialization code or some kind of common code between all of them you're thinking like I'm just going to refactor this to a function and I'm gonna make every callback that needs that just call that first and so we see that for every 15 for every single callback we've got a call out to this initialization function there's actually a way you can do this with something called state enter functions what's really cool about this is it just makes your code cleaner right like it it also helps you between different events you can organize like if you put the I trying to say the enter callback top like then you know that everything that's below that kind of uses that same enter callback and this is gonna get called basically every time that you transition to a new state the way that you would do this is in your callback mode callback you would then change where it says here state functions enter a pendant just gives you a way to kind of write like the common code for a particular state if you have like initialization rules or something like that and then you can see also the first parameter this special callback it just says enter but then you also get the old state as a second parameter so you know you're going in this case from on to off so what are some more things that well one thing is you can even actually insert events into your mailbox and that might not sound all that you know interesting but what's cool is is that Jin Stadium will process those messages before any other messages that happen to be in your mailbox so that really lets you if you want to you know fire off another event and be sure that it's gonna be handled next this is a way to do it and you would give it the type in the content also one more thing when I mentioned too they have a special type called internal internal is there's nothing that the behavior does with it other than basically it's a way for the behavior could know that this is an internal event just at this state machine and we're not we can be sure that it's not something that came in from the outside world I just can't deal with you right now that's what postpone is so postponed is this concept that let's say that I'm a state machine and I'm in nervous or something like that busy state you told me to do something I don't want to do it right now I'll do it later that's what Jen state MO let you do it will actually the message that it's just come in if you return an action as part of the actions from when your callback leaves with postpone it's gonna take the message that just came in its gonna put it back in the mailbox okay and then what's really cool is when you change the states it's gonna replay those messages before anything else right like when I learned about this I was like no way no way like is something engine server that you know isn't even possible without magically and one interesting thing about this I read in the documentation is you can actually emulate selective receive with this so when I'm talking about selective receive I'm talking about you know something vaguely looking like this where you're you're waiting for a message when you get that message you may do something but when you don't get a message when you don't match on that's what postponing it's when you don't message and you hit the after zero and you can be curse what this recurs back the way for does is basically it's like yours changing state in gen state M so you might go from busy or nervous - ready or relieved or whatever and those messages are going to get replayed and you can do you might be able to deal with them at that point and then a concrete example I've got a content but a better concrete example that a little bit okay so one of the blog posts that I found really helpful from Andrew Bennett he was talking about the different ways you can handle timeouts and jinsei dam and a lot of the fun that we have with Gen servers and message passing and Ambala involves like using things like process send after and sending a message to yourself or sending a message to someone else after certain time period now if you find yourself doing that a lot then you might want to think about gen state M because they have three effectively their timers three ways that you can manage a timer and I found out that for me he's thinking about them like timeouts was it helpful and I just started thinking about them more like they're just timers and then it's starting to click a little bit better the difference between these three types of timeouts is basically how they're canceled so the first type is event timeout if you specify this is one of your actions basically what's gonna happen is this timer in this case the timer is gonna fire and after a second however if any message comes in between the time that I've set this action when the timer starts this gets cancelled right so if you have a scenario where you want to you want to do something after a timeout because nothing else happened at all like anything and this is a good time out to use the next one in my favorite is state timeout this is a timer that gets canceled when the state changes so imagine that you are building like let's just say it's a HTTP client or something and you want to model the states that you're in is you're sending a request and receiving the response and so on let's say that whenever we send the request we're going to start a state timeout we're gonna change our state to Oh even response we've just sent a request and now we're waiting for the response if we don't get that response let's say in 30 seconds we're not going to take that the state won't change obviously and that timer will expire and we will get a message the second parameter where you see response time and on screen from this is interesting because left the first callback the callback when I sent the request and I was waiting for the response I started the timer but I also attached this data to it and in this a stream I don't know if anyone's used to gun library from nine 9's but it's very it works really well with gin state and I'll say that but he works off the concept of strings and so a request is a like a string and so we're basically what we're doing is in this timeout we're saying it's a response timeout and if it does happen to expire it's going to pass stream and that from value to call back the handles the expiration and this would be the call to see that because didn't get the request back of course something about trying to retry or do something more intelligent but I'm not gonna risk try to explain that stuff up here and it's not necessarily totally relevant but the point is is that you can use data you can pass data through these timeouts so that's and that that's something that's really interesting to me because then you don't have to like keep a bunch of stuff around in the state in the data right like you could just pass your stream and your front body with the timeout and you want to say like reply to the caller even though you're in a completely different callback you can do that from here right and Jen server about reply you've done that maybe where you take the from a value and then you replied to the later but in this case the behavior will do it for you you just have to have access to the variable and you'll see it's going to send a message error response timeout and then my second action are sorry my return value is next state and I'm going from awaiting response to ready so the third time out is something called the generic time out and you can have as many of these as you want you can you can start the way they're canceled is basically you have to cancel them then once they're started they don't they don't go away so you you have to then set the I think it's the value to infinity to get this thing to be canceled by it by the behavior one cool thing though is that you do give you get to get a payment which we trying out and so you know obviously like you can patent match on that and handle things differently so one of the things I really in this talk is because we have performed we have performance on par with gender or we have semantics that are identical from the clients perspective the gen server there's this idea that architecture is about irreversibility or reversibility and that's what I'm trying to say here is that you can stay in your assigned later on you know this is this is our way out of you know I don't want to do this anymore or whatever you really don't have to worry about from the clients perspective changing anything else because the semantics are identical gen server you do caste and call you have the same semantics there there is no no difference effectively so the client API from the clients perspective you know it doesn't change there could be any number of things going on behind this interface but it could be using gen state change and server it doesn't matter what the semantics are going to be equivalent and so that's I guess my argument is that you know people want to try it there's a little bit less risk because you can back out to tensor - oh alright so one of the things that I really want to get across to you is when I said earlier that we have this is all this is required basically if you want the first two resources here for the standard library documentation they they constantly reference something in the design principles guide so you don't want to have both of those open at the same time read them rather than trying to you know multi-monitor and then I do want to thank Andrew Bennett for this blog post it's a it was sort of at a point when I decided that I wanted to learn more about Jenn State and his blog post really sort of propelled me past I don't know like what felt like peer pressure did not use it so I felt like somebody else out there thinks it's cool and then if you're brave like I really would like to recommend that you take a look at the Gem State in the source code and early because that's something that the documentation there in line is actually quite good and it helped me just make sense of a lot of the mess I guess that's all I have really that gives you a good idea of where is where the the pitfalls might be with Jen Stadium and the types of things that if you are beginner you can come back to this and sort of reference like you know how the simplicity of it [Music] right right yeah I would argue that maybe oh yeah so the question is when would you know how do you know like when to use it with the intuition there be I do well what I timers if you find yourself doing like process send after a lot if you're sending yourself a lot of messages that involve you know specific times or if you were doing obviously some things that can be represented as a state machine don't always make total sense upfront like they send them HTTP requests if you can model a process as a step by step process and I you have a good chance you'll benefit from this and it does provide you like I said with the sort of being able to emulate selectively received you have some ordering capability if you want to handle certain messages in a certain order so that's another intuition you have know some ordering dependencies between your messages yeah I can't does anyone have any other ideas like that's uh that's mine that's my rule done what else back there yeah I tend to forge in servers I tend to use a struct the same name of the gender itself yes as the state and I'm given that that's more complicated than a simple atom I'm wondering if that's also a pattern that you've used and if you found specific cases where one approach is better than the other yeah yeah I said it's one of the I repeat the question so you're asking basically like you use a struct for Gen server to hold your state and in this case is there a benefit to doing that as well no it seems that the actual state here has to be an atom is there oh okay the actual state has to be an atom yeah so yeah that that's a I would say that you would put that struct in data right yeah just if you find that in your like say the old way I'm doing it if I find that I'm just flipping a boolean or whatever right or an enum sort of approach then that would then become to state right it's almost like you get an extra degree of freedom because you have a state that you're tracking as well as the data like you can pattern match on both and so that's really where the power comes from yeah and this is the question being like you see state machines used a lot in Berlin but the links are not so much and kind of why why do you think that is why do I think that is I would say maybe the people that write early are more used to thinking about things academically I don't know I mean I'm one of those guys who didn't take the computer science throughout you know so I I'm filling in the blanks but like it seems to me like when I'm writing Jenna servers a lot that I often have a state value like a some kind of a modality that I'm tracking and I think to be honest some of it's just fear and certainty in doubt Jeannette this seems a little weird to use there are some hacks you have to have and maybe that turn the people off from a link sir I don't know but I'm obviously up here saying that we should yeah I think so and that's why it wasn't really a necessary thing to capture the main concepts right and that's kind of what I was trying to get at it so that he was making me commented basically like in early like that using it more in telecom it made more sense but it's not so much an elixir that's what I was kind of trying to get out by saying if you think like a telecom switch because if you think about it you know call you know like a call has a lot of states it could be in but obviously state machines are widely applicable so it's just a matter of finding a model that works for you pretty much it was it's just really fiddly to use and it didn't have any particular advantages over just having a state right right and that's where this I think I'm arguing now I'm challenging that maybe it would help to think of gen stay in as gen server on steroids right that was my design part of the hacker type like I'm gonna try and use things in the ways they shouldn't be used and it actually works quite well so yes there's no there are yeah but I think really you have to develop the I for when you're when you have a state machine you have right before I think of it in a different way so you can actually right right and then you had things in like postponed and that kind of stuff like maybe those messages are valid at some other point you know so that's and again like we did use that it involved when we were writing an HTTP client like I said the post-punk kind of came in when we realized we were only handling a single request at a time and if something would then send in another request to do it would just basically postpone that and then whenever it was done with the first requested process the other requests as they came in so even you know things like that that you're not used to thinking of as a state machine may benefit from from gym Stadium yes sir [Music] okay so the question being when the message goes back on the queue which end is it going on is going in first so it may not actually be that I haven't looked at the source code entirely but it will be handled I'm trying to say are we talking about postpone it'll be handled first before any other messages that come in while that since that postpone was sent as an action does that make sense like I don't know how it manages the queue itself but I do know that they hand it'll process those message before or anything else in the back yes so the question is is it possible to hibernate these state machines absolutely yeah that's kind of a really interesting thing to think about too if your state machine isn't handling messages that often right if you get some energy savings any other questions cool thank you [Applause]
Info
Channel: Code Sync
Views: 1,244
Rating: 4.8461537 out of 5
Keywords: OTP, Erlang, State, Code BEAM SF
Id: KuZ_wp8W09U
Channel Id: undefined
Length: 31min 8sec (1868 seconds)
Published: Wed Apr 24 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.