Farewell Any - Unit, welcome Akka Typed! by Heiko Seeberger

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thank you thank you hi everybody really I'm really glad to be here again at Scala days and presenting one of my favorite technologies akka I just spoke with the are cutting and they told me akka is like the new JBoss for Scala or something not sure we need to discuss that who often who of you has already used akka Oh awesome alright so I don't have to explain all the basic details that's awesome so I'm going to talk about something I really love about akka it's called archetype it's a new module and before I dive into the details let's take a step back or go step back and look at the essence of akka the actor so what is an actor that's one of my favorite actors or dudes but the foundation on top of which akka is built is the actor model which has been invented in the 70s by Carl Hewitt and others and they defined the actor as a fundamental unit of computation so that essentially means actors are the building blocks for your program and actors embody processing storage and communication processing essentially means they can do stuff and storage doesn't mean disk storage or something like that but it means they can have state and I think this is really the essence of factors that they are meant to have non-local potentially distributed state and they do communicate using asynchronous messaging and it's important understand that one actor is no actor they come in a system so in order for actors to collaborate they need to know each other or they need to know their addresses so they can communicate ok I think that's pretty clear and let's talk about the do stuff and Anaka that's called a behavior so the behavior is what defines how an actor handles messages the behavior according to the actor model is very lean so an actor can only do a couple of things so it can create new actors it can send messages to known actors so that means it has to know the addresses of the other actors maybe they arrived via messages maybe the actor has been created with that knowledge already and and this is really important an actor can change its behavior or it can designate the behavior for handling the next message and while that might sound a little weak it's actually really strong because if you think about this behavior which can be changed that really means that you can encapsulate state here okay and we will see that in detail how its implemented in akka alright so we have our con type the good good old akka untyped and we have archetype the brand new one so let's take a look at how they implement the actor model here is protocol the message protocol is like the API of an actor because actors from the outside cannot be or you cannot call a method on an actor from the outside you even don't ever get a reference an object reference to your actor all you get is the address it's called actor F and you can send messages to so the messages really define so to say the API what you can do with that actor here's an example an account we can get the balance so that's a message we send to the actor let's refer to these messages as commands and you get a reply balance and you can deposit some amount and get back an acknowledge deposited and with withdraw it's a little more interesting because maybe your bank does not give you money if your balance is negative so you could get a reply insufficient balance or you could get withdrawn all right that's the protocol and the implementation in a Koran type could look like this that would be very idiomatic acha untappd implementation you have a actor trait you have to extend from and you use a VAR as I said act is really meant to keep and encapsulate state and using a VAR is what most people do with acha untyped and here's the receive method that defines a partial function from any to unit what do you think about that signature awesome yeah it's it's a very very flexible signature yeah you can you can do anything and you get well it's called unit but you get nothing so essentially acha untyped is really untyped or unit time I don't know so the receive defines the behavior an actor really can receive any message and then does something so here when getting the balance we have this nice implicit sender so this actor knows whether there was some other actor who send a message to it and can then reply and here we reply with a balance and with deposit we would just mutate the VAR and so on I think that should be pretty clear by the way if you have questions let me know anytime okay so that's the typical implementation you could also do a slightly different implementation which is changing the behavior of an actor so the received method that defines the initial behavior goes to this method and initializes the account with an initial balance as you can see here and then when we deposit we change the behavior so instead of using a var we change the behavior and that's totally possible in akka untyped who of you has already used that context become okay that's about half of you probably for state machines or things like that and yeah so that already looks a little bit or pretty close to the original definition of the actor model all right so now let's take a look at archetype and there's a couple of important API changes first of all because of being typed your actor f your acted address is typed so having an act ref of T means you can only send messages of type T to that actor please don't use any as an argument then you're back in good old untyped and there's no more actor trait you can extend from but instead you have to define a behavior of T so that's also typed and as a consequence of that there's no more implicit sender think about that why is there no implicit sender what type should it be actor F of what any potentially or nothing but this is a runtime aspect and the compiler would not know okay so there cannot be an implicit sender anymore and also there cannot be an actor selection so that means that we have to so whenever we want to implement a protocol let me move back here where we have like this request reply pattern a command and a reply we need to change something okay because we don't have this nice implicit sender all right this behavior of T looks a lot like in a simplified version a function from a message to the next behavior and that really nicely matches the original definition an actor can designate the next behavior so whenever an actor receives a message it has to tell akka the next behavior and these messages are either of type T or they can be special occur messages called signals like terminated if you watch some other actor or post stop pre restart and in order to create a behavior you go to this behaviors object and that contains a couple of factories like receive message or same and we will take a look at that okay so this is again the protocol for a well that's the Untied protocol and what do we have to do to make that work in the typesetting what do you think who has an idea yeah okay I think I didn't fully understand you mentioned a trade for what exactly aha for the messages that are incoming yeah that might be a good idea because we need to define some type for the T okay great so we need to define a trade maybe even a sealed trade for the commands for the incoming messages what else how can we make our type actor reply yes exactly yes so we have to include the reply to address so whenever we want to be able or whenever we want our actor to be able to reply this actor F to be replied to needs to be included in the command in the message that is sent to the actor so that's more work for us to do right but on the other hand it makes the whole thing more explicit then you can even see in your protocol that this is a request reply protocol and not just a fire-and-forget single way so let's implement a typed actor let's do some live coding please help me if I get lost okay I think you can read that right I'm going to the account the typed account sorry so so the first thing we need to do is define this command right let's use a sealed trait commands a great name in my opinion especially if you go for CQRS or something so our incoming messages need to extend command okay cool and now we can define the behavior I'm using the apply method here to define or return the behavior of command alright then the other thing you already mentioned is the reply to so we no longer can use a case object because we need to include that's too many S's thank you we need a reply to and now actor F is typed and what type should I put here and it is balanced exactly because we're gonna send back the balance is great okay cool that's the one thing here for deposit that's also pretty straightforward we need this type well the type here is compromise missing sorry the positive dot type looks a little ugly but okay and then finally here we also need a reply - sorry lie - of type actor F of something but here it gets a little nasty so what to be put in here insufficient balance or withdrawn yeah exactly let's make trade yeah we could also use an option but what if or neither but what if we have like three potential outcomes so I prefer to use a DTS for that CEO traits so let's call that with sorry with raw reply it's a little hard to type on this yeah anyway with raw reply so we can then use that and it extends with round fly and extends reply okay that's the protocol mission achieved almost so now we also have to implement the behavior so for the behavior as I said we can use the behaviors object which has a couple of nice factories we can be lazy and just do that but that would not serve its purpose so when we don't need any actor context and we don't need it here because the actor context is also like in akka untyped used to create child actors and stuff we don't worry about that right now we can use this receive message that just takes a function from T to behavior of T and we can use nice pattern matching get parents and reply to and then we can say reply to bang balance and that is our balance the balance is given as a parameter to the apply method but the compiler is not happy because we have not yet designated the next behavior which behavior should we now return exactly because we don't change any state okay so our behavior can be the same Anaka internally optimizes that so it doesn't really have to switch the behavior it just keeps the same behavior so that's the meaning of this special behavior okay so um let's also quickly do the deposit and then I can move on deposit has an amount and I reply to and we don't have to check any cases here so we can immediately say reply to being deposited and then we have to switch the behavior okay how do we do that yeah we just call apply again we can just do account and then we do balance plus amount and that's it cool and the same would be true for withdraw and I will not type it but just jump to the next step in migrate sample solutions so it would look like this behavior same if it is on sufficient balance or a competence - amount if it's okay does that make sense all right and for me this looks a little clearer than inaka untyped and another benefit you get from defining actress like this in terms of behaviors is testability because in archetype test kit there's a way to just test the behavior in isolation without the asynchrony and non determinism so without actors without actual actors you can of course also create actors like before and use test probes and stuff but there's the the behavior test kit that allows you to just test the behavior synchronously and I think that's that's a huge advantage all right so that's a couple of more behaviors if you need an act context and a message to you you should receive if you need an early actor context you use a setup setup is a little bit for these things which you would have done in the constructor of your actor okay untyped actor or in the pre-start method receive partial if you want to ignore some unmatched messages because here let's say we comment that we get a nice compiler warning that the match is not exhaustive okay so that's great in most cases sometimes don't want to match on messages because you know this message cannot be sent okay if you have a state machine for example in some states nobody will ever send a message of some type and then receive partial is your friend so you could do receive message partial and then the sorry then the compiler would no longer complain but then of course you could forget things so I always a little bit or if I do that if I add the partial I'm a little bit yeah yeah is it necessary sometimes it's necessary alright um stopped well guess what behavior stopped will do that's the way to stop an actor or and I could to stop itself in archetype you no longer can stop arbitrary actors so you can use context to stop a child actor or you can just return stop behavior to stop this actor and that's it and that's also receive signal to just receive lifecycle signals okay the actor context is again like an untyped the power api it has a lot of methods so two of them are spawn to create a child actor and message adapter to ingest external messages Oh what does that mean okay I will give you an example so let's talk or let's think about transfer so we have two accounts and we want to transfer money right and let me move on to the skeleton for the type transfer so here's transfer what we are going to do we create a child actor for an account and another one we call the one from the other two we use context at spawn in order to get the context we use behavior setup so we have an early context this is like our main actor it has a seal trait command with not a single inhabitant so you cannot send any messages to this guy which is quite typical for the main actor I would argue and then we create a transfer actor which we still have to implement and we watch that and the only thing our main act does in its behavior its receiving the terminated signal for the transfer and then those behaviors stopped which means the main actress stops which means the whole active system will terminate okay and in archetype in order to create an active system what you have to do is you have to pass it the route actor or the main actor whatever you want to call it you can no longer call actor of or spawn or some method on an active system to create arbitrary many top-level actress there's only one route actor you pass the behavior into active system active system will create it for you and all the other actors you want to create have to be child actors of your main actor okay I think I won't implement that but just move on and show you how to implement the transfer could look like so the first thing we do in the apply method here we take an amount that's the amount to be transferred we have our from and to actress from is an actor off of withdraw and to one of deposit we use the context to send the withdraw message to from that make sense right with the amount and now this is interesting let me again go to the withdraw message the withdraw message takes an actor F of withdraw reply okay we need to provide an actor so that can receive a withdraw reply like an insufficient balance of withdrawn our transfer act here has its own sealed straight command it can not receive the withdraw reply in ARCA typed you could send anything to any actor there it was really easy to implement request reply because any actor could receive the replies from another actor it's not possible here we can only receive in transfer our command subclasses but the withdraw reply is from account and not from transfer so therefore we need this message adapter thingy and that just adapts from the withdraw reply which could either be an insufficient balance or withdrawn to an internal message so we have to more or less duplicate the messages as internal messages okay so as they are commands I call them handle insufficient balance and handle withdrawn and these thing so that is a little boilerplate e I have to agree but it's necessary for the type safety so first we send the withdraw to the from and then we define our behavior so here we use withdraw partial sorry receive partial to either handle the insufficient balance or the withdrawn okay we don't wanna handle deposited because that cannot happen at that stage right the only responses we get from the from actor is either insufficient balance or withdrawn the first case be abort we stop in the second case we know the money has been taken away we can now deposit it to the other guy we sent deposit to - and again we have to do the message adapter thingy to get the deposited reply in to handle deposited which we will then handle and then print transfer done and stop does it make sense if you have questions let me know okay so let's just run it and see whether everything works as expected we are transferring 50 so that should work it says transfer done which is great and you can see that the program has terminated so even receiving the signal seems to work properly if we try to transfer too much we should get the abort message okay so that all looks pretty good okay so if you wanna migrate from one type to type you have to keep in mind two or three important things so first you should use a DTS for the message protocol so you have to define your sealed read command or call it message if you prefer that or anything so yeah user an ADT so the compiler then can help you telling you okay your match is not exhaustive you have to add this or that command to your match you have to replace the implicit sender with an explicit reply to address or actor F and if you want to consume messages that are defined on some other actor you need to use those message adapters and that's essentially the tweaks you have to apply what I really like about ARCA typed is that it can completely coexist with the untyped so there's only friendly competition amongst them so if you import the various methods defined in this adapter or package object everything between untyped and typed will work for example you can use an untyped actor F where an a-type actor F is expected and vice versa so you can send a message from an typed act to an untapped actor or an untyped actor can watch a typed actor and vice versa there's a small difference regarding supervision which I will which I will show you in a moment so let's first take a look at this coexistence so we can write an untyped transfer that uses these typed accounts so what we have done here is we have written a typed transfer okay and let's just take a look at an untyped transfer I call it mixed transfer here where is it where is it mixed okay here's a transfer and that is just a traditional class that extends actor the parameters it gets our typed actor RAF's and then when we send this withdraw to the type from we include self as the reply to and as you can see here this underlined means okay something's going on some please conversions are going on and that is because of this import second line or line 21 the adapter import and you probably also can see it here and that works exactly the same way like the typed account it compiles and I hope I hope you believe that it also runs the same way and I think this is really great so it means you can start adding typed actors to your projects to your ARCA projects you don't have to rewrite everything in a Big Bang but you can start adding new actors as type actors and get used to them and see what they are good for what is not that good if it's not that good let the ax-cut you know they're open for feedback and yeah this coexistence I think is a very very important aspect and actually if you look at the the akka libraries which are on top of a corrector like for example streams or HTTP or cluster or persistence some of these have been ported to typed but usually not complete I mean our persistence type is a complete rewrite whereas the various akka cluster type modules just have a thin for say the type facade on top of the untyped and that totally makes sense because so the are cut in can could slowly move to typed if they want to under the hood for the implementation okay so one more thing I would like to mention is a super vision and the difference to untyped is that in archetype the 40 actors are stopped by default which means if there's an exception the actor gets stopped do you know the default in akka untyped what's the default Enoch are untied no yeah in most cases is restart yeah so there's a couple of exceptions which are treated in a special way like if the exception occurs during is initialization for example or if you don't handle the terminated on the actor will be stopped but in most other or in most other cases yeah the actor gets restarted in my personal experience that is not a good default and it looks like the akka team has arrived at the same decision so most of my ARCA projects I use the supervisors the the stopping strategy so I can type also has a stopping strategy and I use that for most of my actors as the default and yeah it's the default in archetype now and if you want to change that you can supervise a behavior so what you do is you have a behavior and then you wrap it in behaviors that supervise okay so it's a little different it's not that you have to define a supervisor strategy at the level of the parent actor but instead you define your behavior to be supervised in some way and let's take a look at one more example a calculator actor so it's a huge actor for this small example sorry for that it's a calculator or you can add subtract multiply divide and divide is interesting so as you probably can guess if you send divided to this and N equals zero you might get into trouble right and our program here what does it do so here we just create the calculator actor sorry that's the behavior we're creating it in the spawn method let's be precise that's the behavior we initialize it with zero and then we send an ad 42 because 42 is always a good value and then we divide by two and then we try to get the value okay let's see what happens if we run that little program okay some exception has happened like expected we get an arithmetic exception by zero and it looks like we don't get any value back okay and it says stopping because calculator terminated let's again look at the code so when we receive the terminated signal we get this and yeah the get value looks like it's not really gotten so yeah the actor has been stopped that's the default as I said and now let's switch the whole thing a little bit so instead of not supervising it lets supervise it so now we do behaviors that supervise so we essentially wrap our calculator behavior in this supervised block and in order to get back a real behavior because that's just a supervised we call the on failure method and here we provide an exception type and then in this case I decided to resume so if we divide by zero that should essentially just be ignored okay let's see how this works whether we get our 42 out of it gray we get it so that's how supervision works in archetypes and I personally really like that because even when I was writing super special special a supervisor strategies but the stopping strategy but real ones in in our current type I never had the situation where I had to build a huge pattern match like case full exception to this case parks exception to that so you no longer have this decider function that goes from arbitrary throwables to some decisions like stop or restart but instead you just provide one exception type and that's it of course you could go for throw oval or exception but yeah usually in the code I've seen there's one particular type of exception that can occur maybe JBC exceptional whatever and you want to deal with that and yeah that's you can do in in archetype alright so that was supervision and that almost takes me to the end of my presentation the current state of archetype is it is still an experimental module or multiple experimental modules so there's tight API or type module stars available for archive assistants berries cluster modules distribute data and even for streams I think there's a very very small addition just for the source and sync dot act RF to be typed now I recently gave a workshop on Monday and Tuesday totally based on archetype and you can build real-world systems completely on top of archetype so everything is there you need and question is what's next so it's almost feature complete hopefully within the next releases some smallish missing features are added in my opinion its production ready the API may change okay and that's what the meaning of experimental is if you go to the documentation which is really good it says ok danger area but that for me just means the APR may change that's okay for me I don't think there will be two big changes there have been big changes over the last half year but nowadays I think there will only be smallish ones hopefully and yeah please give it a try and get good feedback there are a couple of great discussions on the issue tracker if you're interested so yeah hopefully I could inspire you to give it a try and thank you for your attention I don't want to stand between you and lunch but if there are questions I'm happy to take a couple thank you who is the owner of the microphones because there's questions over there hi so in a car types what happens to the actor event stream so now you can publish something to the event stream and subscribe to events what will happen to that that's a good question because I never use that thing I wouldn't know why I should use it but I guess it's still there because I told about this coexistence so actually everything in archetype still runs on the untyped actress system under the hood there is a type system but that uses the untyped under the hood so I guess and you can convert the untap to typed and type to untyped so you can get access to the untyped actor system which exposes your event stream and you can just use it I guess but I didn't do that other questions over there could you please just just wait for the microphone so the others could listen as well thank you you mentioned you mentioned that akka streams is also changing in the course of chant going to typed what are the changes for akka streams concerning that I don't think there are big changes um so the changes I mentioned is the source and sink dot actor F these are methods that formally of course just or okay so that's the economy module and there's the akka streams typed module and in the ARCA streams typed you get typed actor s okay other than that akka streams is typed so it's a nice fit I would say I think the map async will also be so currently it's a little hard to do the ask pattern in archetype because you need an implicit schedule and everything so there will be some some some help us to make it a bit a little bit nicer more questions yeah okay yeah in in scar three they introduced union types and now you do a DTS and shield traits will be more explicit if you use like a union type in the XRF time that looks pretty promising yeah but I don't think akka would work on dotty does a can work on dolly guys so the haka team doesn't know so we will probably have to wait a little bit and enforce the collaboration in that regard yeah but that looks pretty promising I would say your preference was using edit ease and this is a bit different it looks like it harden it you told us your preference was to use a TTS with the seal trait yes exactly instead of using an eider or something like that so first of all sometimes you have so if you have these diverging responses sometimes you'd not only have two but three or four or whatever that would not work within either and even if your protocol evolves over time and just you start with two you might then add a three so then you're lost within either then they'll do a larger refactoring so therefore I prefer a TTS but of course it is totally possible if you just have like a or B as a response you could use either yeah if you prefer that I personally don't like it that much even even options I mean they are just wrappers and even an option could be expressed differently but yeah it's it's possible I prefer for various reasons to not use either or options but a DTS it's more flexible okay maybe one more question here the first row thank you what happened with the pattern such as a score pipe - okay what happened with a score pipe - so asked is there it's more or less the same it's a little different because of the reply to that now has to be fed into the message that is sent to the actor so therefore the ask operator not only takes a message but instead takes a function from actor F to message if you think about it it becomes obvious but then if you forget about it it looks weird again so yeah but ask ask is there there's no pipe - at all I think I asked Patrick and he told me it's no longer necessary which I don't totally understand so yeah type 2 is not there you can just yeah you can you can just broke with the future and send it your so you have to essentially do it your own I want complete Handler and send to yourself and please consume everything you take from the actor context before out so consume everything inside the behavior of the actor and not a synchrony asynchronously in this callback you give two uncomplete okay thanks I'll be around if you have more questions at lunch or later today I don't want to stand anyway as I said so enjoy your lunch and thanks for your attention [Applause]
Info
Channel: Scala Days Conferences
Views: 2,238
Rating: 4.9285712 out of 5
Keywords: Akka, ScalaDays, Berlin
Id: YW2wiBERKH8
Channel Id: undefined
Length: 42min 22sec (2542 seconds)
Published: Thu Sep 20 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.