Live Coding with Rust and Actix

Tensor Programming · Intermediate ·📐 ML Fundamentals ·7y ago

Key Takeaways

This video demonstrates building a web application using Actix and Actix_web, with a focus on live coding, chat application development, and database interactions using Postgres and Diesel.

Full Transcript

hey guys can you guys hear me you for whatever reason it didn't give me the preview stream but whatever it should be all right let's see got a few people saying it sounds alright which is good alright so let's get into this so for the interest of the people who are probably watching this on YouTube I'm just gonna go over what kind of happened yesterday and for the interest of people who weren't here yesterday so yesterday we were kind of doing something similar building a blog application using the act X library with rust and I had some technical difficulties both with the library and with the stream the console stream to kind of go down for like 45 minutes or some crazy amount of time like that and of course I didn't realize that at the time and I ended up rambling to myself for that entire period of time and by the end of it I was just wiped so I figured whatever I'm just going to stop the stream and because a huge chunk of it was missing I also deleted the video so I decided okay I still want to do this you know I still want to show you guys programming a application using actives and so I decided I chose a different type of application I went back and I read some of the documentation found out the issues that I had and now we're gonna actually live code a chat application instead so we're still going to aim to build an application that can be consumed as an API by any kind of front-end in this case we're going to consume it with a flutter application and that application will be built in a separate live stream already so I think we're ready see all right so just to kind of go over what we've got here so I've kind of set everything up to begin with I've set up diesel here and I've brought in a bunch of the libraries that we're going to need so I brought in act acts acting sweb chrono diesel dot environment failure futures RTD to the serade libraries and then the unique user ID library and I've got all this on a github repository which I can link in the chat let me see if I have it right here actually it should be in the description of this video but just in case let me link it in the chat and as we're going through this I will be updating the repository can you integrate the off into that flutter video as well I mean I guess I could probably take that old video or that old application and use it as sort of like a base and link it to this API I don't know I'll think about it all right so we've got all that set up now I'm just gonna kind of go over what the application is going to be structured like so the idea here is that we want to create a few a few HTML our HTTP handlers so the concept here is user can log in and they log in using HTTP and our login won't have any authentication on the back end but we can add authentication to whatever front-end we create the user just has a username which gets sent to the backend and then what happens is the backend sends the last twenty messages that have been sent in the chat so we get a chat history immediately by sending in our username all right the other main handler will be the ability to send in messages ourselves so we need to have a username and a body and then we build out a message and we'll talk about what the message actually looks like and then that goes into the chat and that will actually get sent into a web socket and then the web socket will be updated live of course because it's a web socket and then I think there's another handler I want to implement let's see all right yeah of course the WebSocket handler so we'll be able to listen to the WebSocket and watch as the messages populate and of course all of this will be backed by a Postgres database and yeah so we'll have for persistence on our chat application in our chat room yes F that's why I said maybe it would be worth using the other F or C though I might implement some kind of manual authentication rather than using firebase if I decide to implement authentication at all but we'll see all right so to get started here let's create some migration so let me show you guys my terminal I think it's does it I forget what the command is diesel migration I think creates and then the name of the migration which will be messages No it's not create its generate then we'll call this create messages because we're going to create a messages table and that will generate two SQL files for us and a folder and now we can go into this folder and we specifically want to go to the up SQL file here and we want to create our table we want to say and I think it's create a table I'll call this the messages cups and oops hang on with got to throw my cat out of the room hey guys be right back just give me like two minutes you okay sorry about that so where were we okay we were creating our messages table and so we want an ID the ID will be a UUID type primary key and we'll have it be not null and that needs to be a comma and we'll have user name which will be a bar car our bar chart size 10 it'll also be not null and body and this will be a text and again not know and then finally we want to have time stamps and I think we'll just call this TS and this will be a time stamp type and again not null and that should be correct SQL let's see oh well I got a $20 $20 donation from zeph oh thank you man you didn't leave a message but thank you and you said for all the help you've given me and all the things I've learned throughout your videos well thank you I appreciate that all right so now that we've created our sqr we need to of course migrate it so let me clear this out and then we can run diesel migration or migrate rather run how does it run what is it these are all our migration rather I think it's run yeah run and that will migrate our database for us what you did and yeah so now we have our model in our database and we have our schema file in our rust application and also our diesel Tommo should be pointing towards this schema file and of course we have our dot e and B file which has the database URL in it so with this all built let's go ahead and create the model for the application using the rust code of course and so I'll create a file here called model dot RS and essentially we're going to kind of follow the well hang on let me make this a module main not mod main mod module model rather and essentially for our model we want to make something that's similar to what we just created in that SQL document so actually back in main for a second we want to make some imports here and I know I mentioned yesterday and I'm going to reiterate this today that actually with rust 2018 you don't have to use the external crate keywords so anything that you've brought in with your cargo tummo file is accessible from any file in your application and so you don't need to explicitly bring it in using the external trade anymore that being said there are some advantages to using them for specific crates and I'm going to use them for Act expanding also going to use it for diesel and I'll explain why I'm doing this in a second I'm also going to put macro use here as well now back to the model we need to of course import a bunch of stuff so we're going to need to use and since I've imported that stuff I can actually refer to crates and then I can refer to act X and then I can refer to pre lude and this will allow me to directly grab the external libraries or it was a part of my application and that's why I brought it in using main that way even though I don't have to and of course we can do the same with our schema which is an actual file and this is the messages table we're gonna need to use chrono this is a library that deals with time and we're going to need this type called native naive date/time which it has both the day time as well as the the what's it called and I'm having a brain fart the the time zone yeah there we go we also want to bring in sir a derive deserialize and serialize so that we can derive them on our model and then finally we need to bring in UUID UUID type because our ID will be that type as well now I don't know why we're getting an error here oh yes because I didn't add it as a mod sub mod to our main application so let's do that and that should fix that all right so the model here let's first derive for all of the different traits that we want to add we want to add the debug traits the clone trait the serialized straight to the deserialize trait the queryable traits the insertable traits and then the message trait of course debug is something is built into Ross Amos clone debug allows us to see the code if we want to print it out and then clone will allow us to clone it rather than borrow it serialize and deserialize both come from sir a derive which allows us to serialize and deserialize to and from json then queryable an insertable are two traits that come from diesel allow us to query this data type in our database and insert it in our database and then finally the message type comes from the act acts library and it allows us to declare this type as a message type and I'll go a little bit more into what a message is as we get into the act X library so we also need to declare where this model is going to be in our database and the table name will be the messages table because that's what we call that I believe may check real quick yeah messages so now we can create our public struct I'm going to I'm going to call this msg because we already have a message type and I don't want to have to run into any conflicts so we'll have our ID which will be a UUID then we'll have our username which will be a string then we'll have a body which will also be a string and then finally we'll have our timestamp which will be our naive date-time format we're also going to create another struct in this file and I'm just gonna set it up right now but we won't actually have the we won't be able to really put the data in it because we need to create our actors first so I'm just going to call this the app state and the Upstate will eventually have an address with our database actor in it and then an address with our WebSocket actor in it so I'm just going to leave this here for now so why is this throwing an error let's see how messages spelt it wrong and let's space it out a bit okay so just keep in mind that we're going to put our actors into this appstate struct and we're flesh it out as we're going along here and actually work let's go ahead and create the actors now I should do a facecam yeah that's not gonna happen I don't particularly like the idea of doing webcams and there are various reasons why I don't do itself um if you're not familiar with Russ you can just kind of follow along you're not really gonna learn rust from this app though if I'm being honest but uh I don't know maybe you'll find some value out of this we are gonna be talking about actors so maybe you'll learn about the actor model all right so we want to create our actors now and what I'm gonna do here is beautif older here called actors and inside of it let's create our mod dot RS even though we don't really need this and we'll also create our DB actor or rather let's just call it DB dot RS file and of course we need to make this a sub module of this and we want this to be public too and we need the actor folder to be a sub module main so let's put it here all right so in DB we want to use our crates Act X we're going to bring in the actor type the sink context type the message traits and then the handler trait and I'll explain about these as we're going we're also going to need to bring in our model model msg and we want to bring in our schema as well so that we can reference it directly we're going to be using act X web as well in here specifically the error type and because this is our database we're going to need diesel r2d2 and we'll get the connection manager type and then the port type so that we can of course connect to our Postgres database and then create a connection pool and speaking of that let's grab the PG connection type and we're also wanting to expose diesel or Prelude with a glob import this will give us a bunch of utility functions and stuff and then we need sir a derive deserialize if I could spell there we go and finally we'll need UUID and chrono local and of course rust F and T is deleting my imports which is annoying let's see let me try and reorganize these so that that doesn't happen so what actually is happening here is rust F and T is trying to put everything in alphabetical order and as a result of that it's actually deleting some of the imports so specifically it's deleting this one and now it's the deleting another one so let's see let's try move these around this is really annoying it's it's an actual issue that they know about but they still have yet to fix it so alright that seems to be alright it seems like that one didn't actually delete anything all right and let's see yeah that looks about right okay for our actor our database actor will create a struct here we'll call it DB actor and inside of this struct we want a single value which will be a pull type with a connection manager inside of it and inside of that we'll have our PG connection so this actor will essentially just have the state it allows us to connect to our database you now we also need to define the different messages that we need that we want to send to this actor the first one is a user message if you guys remember when I explained how this application is going to work users going to log in and they send in their username and so this is what this message it does essentially we send in a single string to the database actor and then it does something and we'll we'll expand upon what that is we also need to define another message which we'll call form and again will derive debug and deserialize and the form here will have the user name as well as the body let's see rust isn't that complex the schema crate is the schema for our diesel Postgres connection so we created our Postgres migration in in the migrations folder and then when I ran the migrations this like macro was generated and this macro essentially just gives us a bunch of handler functions and utility functions who allow us to directly call to the database without having to use SQL they don't make more sense when I it'll make more sense as we get into the actual Rajic here but yeah and that's basically what it does how you doing as a cane hopefully I'm saying that right or is it hanging cayenne cayenne sounds about right okay so we've got our two messages here so now we want to implement the actor traits for the DB actor type and what this essentially does is it allows us to define the DB actor type as an actor and we need to define the execution comp text which is essentially just the state that's inside of this actor so sync context because we want this to be synchronous and we'll pass in a capital self which is just the DB actor type itself now of course for this actor we also need to implement the messages that we created so the user message in the forum message so that the actor knows how to recognize these message with these messages when they're coming to and from the actor itself so message say for forum and so when we implement the message trait type we need to define what kind of result we want to get back from pushing this message into this actors mailbox so if we push a forum into our database actors mailbox we want to get back a result that contains a message or an error for the user for the user message which I'll just copy this we want to return not just a single message about a vector of messages or an error so as I mentioned before when a user logs in they'll get the last 20 or 30 or so messages in the chatroom from the database and that's how we're doing this so we send the user to the database actor and then it responds with a result with a vector of messages inside of it so now we need to define what's called the handler for this or this actual actor and we need to create a handler for both of the messages one for the user and then we'll create another one for the forum for the user the handler is basically how it's handling this message again but it allows us to have a little bit more fine-grained control over how this is working so here we're gonna specify again the result and again this is going to be exactly the same as the results up here so like that and actually for user we're going to return a vector messages like that and we also want to define a function in here called handle which gets called when the message gets sent into the actor let's say user type and we're gonna also need the mutable cell context there we go and this is going to return a cell result there we go so our handle gets called if the actor is executing and it gets the message then the handle function is called so what we can do in here is define the logic so what we're gonna do is get the connection for our database so this is a PG connection and we can get it by clawing self zero which is the type right here the poor web the connection manager which is wrapped in the actor we can call get to actually get it and unwrap it and that gives us our PG connection reference and then we could say let messages equal schema so now we're going to that schema that we created before and we're going to call it schema messages should be messages which is the name of the the table that we created and then we can call table and we can specifically now call some methods on this we're going to call order and well order this by the time stamps in a descending order so I can call schema messages TS dot descending inside of order in that and that'll work that way and let's space this out a little better and I want to limit the amount of messages that we're getting back by 20 so we only get back the last 20 messages and then we'll load those messages and we want to cast them as a message type and we'll pass in our connection here and then we can call unwrap and then to return from the function we can just return okay with messages inside of it and just be messages like that so this is fairly straightforward if you think about it it's it's just pretty basically ping the database we get the you know the data from the database and then we just pass it back inside of a result Danya I'm glad I'm doing more Russ's where I like this language a lot I've just I've been doing a lot of flutter because that's the demand currently alright so now let's create the handler for the form and in this case let me just copy a lot of this because we're also going to be creating a handle function and a result and all that so in this case our result is remember it's just a message and or an error rather than a vector of messages and with handle we're passing in a form not a user and we actually need access to the form and let's clean up this part here so what we're gonna do here for this one now and actually we're going to need the PG connection so I'll clean up that part I'll say new message so we will just create a new message using our message struct and so we need to define the different fields here so the first will define the UUID which is the ID we'll use new v4 to create our unique user ID then we need to define the user name which is coming from the form type that was being passed in as the message let me get rid of that because it's annoying we can just say MSG dot username and then for the body it's just MSG dot body and then for our timestamp we'll just call local now to get the current time and then we want to convert this into naive local which is the current time with the but the timezone connected to it you we now want to insert this message into the database and we can just do this by just saying what result to equal diesel insert into and we put in our target which we can just call from schema so schema messages table will be our target the values that we're going to insert are a reference to our new message variable and we also want to get a result from our connection and we'll unwrap this as well and then finally we can just return the result inside of an okay see looks like there are errors no they went away okay so these look right to me so this is just the basically this is just the logic for our database actor but our database actor is not the only actor that we want to implement in this application we also want to implement the WebSocket actor as I mentioned before so let's create a WS dot RS file as well this will be for the WebSocket and I'm going to grab some of the imports from dB we'll need most of this stuff from act X we'll need our model you and I think we'll need the unique user ID as well and of course let's make it a sub-module here so that we can actually connect it to our application for the stuff that we're importing here we don't want sync context we just want the normal context type because this will be a a asynchronous context which is the normal type and then we also want to bring in a recipient type recipient refers to the address of an actor that has sent a message and we need that for various reasons so let's see we have actor context handler message yeah that sounds about right we have our model we're also going to need standard collections hashmap because we're basically going to create a big hash map here yeah I don't know what it is RLS is a little slow sometimes so it can take a little while to catch up take a few seconds it doesn't really bother me that much but it's a little annoying sometimes all right so why am i implementing things let's create the structure here for our WebSocket actor so WS actor is the name here and this one will have a single field in it which will be a hash map and the keys will be unique user IDs and then the values will be a recipient address with a message type inside of it so it'll be an actor that has a message inside of it and basically the idea is that each of the fields in this hash map will be like a session of a user that's connected to our chat application so we'll have multiple actors each one will be responsible for dealing with the users and then we'll log each of the actors in this WebSocket actor we need to derive some other messages that we want to send around to this actor so first one will be a connection message or a connect message rather this will just take in the UUID and then it will also taken an address which will just be a recipient of message type like we have above and then we also need to derive another message this one would be disconnect and basically what we're going to do is for Kinect we'll just add it to our hash map and then for disconnect we'll remove the value from the hash map just using the ID of course the WebSocket actor needs to be an actor so let's come here and implement that and the context is just a normal context with our WebSocket actor inside of it so just with the hash map inside of it so again this is just the execution context for the the actor itself and it just defines the state inside of the actor you so now let's create our handlers and this should just be handler first let's start with connect and for this one the result meaning the return type is just going to be a union type so it's just empty again we need to define a handle function here this will take immutable self it's important to note that with a actor any state that's inside of the actor itself is completely meetable with acting so these are not immutable like a lick sir these are completely mutable the actor itself is not mutable but the state inside of it is so we need to account for that and that's why we pass in a mutable stuff like this then we want to pass in the connection message and then we're also going to reference the mutable self context and this function is not going to return anything and the reason why we don't have to return anything is because our result is a Union return type meaning it just it's literally a non return type so we can go as self dot zero to get access to our hash map then we can call insert and first we'll insert the key which will be message dot ID and then the value which will be message dot address and let's see storing an error I think that's a fake area it is now let's copy this and implement it for disconnect again for disconnect the result will be empty and then we also want to implement the handler function or the handler function rather for this we'll call it self zero D move then we'll pass in a reference to message ID and then this will just remove any field that has the message ID which will be the UUID and it will also remove the actual key associated with it as well we also want to allow these this actor to accept a message type from our model so we'll implement that as well again type result is just going to be Union type and again we want to define the handle function let me just grab this and let's see and for this we'll just say for a WebSocket in self dot 0 dot values so we're iterating through our hash map we're iterating through all the values in the hash map we want to call WS these are essentially just the actors addresses and we can use the addresses to send data and in this case we're going to send the message to to those other actors so essentially what happens is when a user passes a message into our application it gets pushed into this actor and then we need to spread all of those messages out to any of the users that are currently connected to the application through the WebSocket of course we're getting an error here I need to clone this and that should deal with that error whoops yeah there we go and it might have some other issues as well and says here yeah doesn't want me to implement it this way but this should be perfectly fine so I don't know why it's complaining all right so we our database Acura and our WebSocket actor and now we can actually go back in the model and implement this app state just by saying DB which will be an address with a DB actor inside of it and then the web socket which will be an address with our WebSocket actor in it so our app state just holds references to the two actors that are being used and of course we need to import from our actor from our actor these two types so that we can actually modify them so DB DB actor and then WebSocket WebSocket actually like that and of course this is a fake error yeah alright we also want to implement a session dot RS file now the session here is actually the actual session so user drugs in session is created and we use this session to determine whether or not we want to timeout a user and we also are going to use it to pass around the messages and stuff through the actual WebSocket this session will also be a actor so the websocket itself will actually be derived from a bunch of actors and yeah so we need to bring some imports here let's see we're gonna need this and we'll make that a glob import will need act X Factor er and ler running [Music] stream handler also need also need our actor stuff so our actors will need the websocket things I believe [Music] both the connect and disconnect messages what we're going to need we'll also need our model and we'll need both the app state and our message type we'll need act X Webb is we're going to start to interface this with our web side of our application so our bringing in the WebSocket logic specifically a message for WebSocket a protocol error for WebSocket and then the WebSocket context which allows us to define the context of an actor as a WebSocket as you can see here it says execution context for WebSocket actors then we have to bring in our standard time type and we'll bring in duration and then instant now instance a little strange I'll talk about in a moment but it's a little odd and then finally we also want to bring in I believe the unique user ID is what we'll need yeah all right that should be enough let's see if it destroys any of my imported snout okay so in here let's create our session structure and this will have this will be a tuple of two values we'll have our unique user ID for each session and then we'll have an instant and the instant type again like I said I'm gonna have to explain it a little bit so the instant type is created it's essentially a sort of like a time stamp except the thing is is that it doesn't actually produce any kind of time unless it's used with a duration so you can create an instant when a user logs in but it doesn't have any kind of meaningful data inside of it unless you apply a duration to it so for instance user logs in say at 3:30 and then we add five seconds to the instance the instant then we can find out yeah they actually logged in at 3:30 it's sort of abstract but it's a good way to to makes time and durations together inside of rust you guys seem pretty quiet let's see under wonder it's on top shout and set a live check so when I put it on live chat you guys are still pretty quiet so session again is going to be an actor so we need to implement the actor trait for session in this case that we're going to actually implement some functions rather than just implementing the context context here will be a WebSocket context with us in the self and then we also want to pass in our app state so for each WebSocket connection will have a unique user ID the instance and then will have the app state and this will basically correspond with each of the clients that are connected to our application so each one will have their own app state and they'll have you know their own unique user ID and their own instant all right and actually before I create the functions in here let's also just create an implementation blog for session and then create a method here called heartbeat and the heartbeat method is going to be called every few seconds to determine whether or not the web socket is still connected or not or the client is still connected to the web socket rather so for this we'll pass in a reference to self and then the context which is the web socket context was self and then app stayed inside of it and what we're going to want to do is just say CTX run interval and we passion a duration here and so we can use that instance of that instant rather and this duration to determine how long a user has been connected to the web socket so in this case we're going to check every five seconds we're going to pass back a anonymous callback function here this takes in the actor and then it takes in the context and let's see need a semicolon there and we want to check to see if instance now duration sins and will pass inaccurate r1 which is the instant inside of the actor context or the actor itself rally the session this thing here this part of our session I'm gonna see if that's greater than a duration from seconds 10 so if a user hasn't hour if a session has been logged in for more than 10 seconds and it hasn't done anything then we want to disconnect them from the WebSocket so we can print out heartbeat failed and then we can call CTX states WebSocket and that gives us our website connection and then we can send a message and we can just send our disconnect message to our web socket actor and so we'll send disconnect with ID and then we'll grab our ID from our actor from our session actor and we'll pass that in and that will then be sent to our web socket actor like I said and then our website connector has this unique user ID inside of the hashmap it'll find that UI that ID and then it will remove it and then we'll call CTX stop which will stop the execution of this session and then that will end this little closure here then afterwards we can just call CTX ping and we'll pass in just an empty string and that will just ping the rest of the sessions to see if they're still active and if this will happen every five seconds because this will run through if this doesn't happen then it'll just keep going and it'll keep pinging and pinging and pinging so it just keeps the WebSocket arrive until nothing's happened and then it will just kick the WebSocket out hopefully that makes sense anyway alright so now we can define this started function so the started function is executed when the actor is started so actors have like a life cycle like most other applications and our processes or whatever you want to refer to them as and in this case our actor has a started state and this means that this function gets executed once the actor starts and it only gets executed that one time so here we can say self dot heartbeat and then we can pass in our context then we can get our ID UUID will be a new before you can say self dot 0 equals ID so create our new unique ID and then put it into our session and then we can get the address of our of our actor and then get the address of a recipient actor using our context like this and then we can use that to call CTX state websocket do send and send a connect execution function our connect object or not object but data structure to one of our WebSocket actors with the new ID that we just created here and then the address which is the address of this session and basically what this does is it's just giving the websocket actor the ability to send messages back to this actor to the session actor that connected to it so by sending it the recipient address we can now send messages back and forth between the two actors so you got to keep in mind that with actors they're all referenced by their ideas each one has their own address or ID if you want to think of it that way and that's how you can refer to the actor itself and that's how you can actually manipulate the actor and so when we want to send a message to and from an actor we need to have the ID of the actor to be able to do so all right you also need to create a stopping function and this is a function that gets executed when the actor is stopping this will take in it's mutable self and then these context again should be a mutable assault context and then this is going to return a running type and running is an enum and we're basically just going to use this to stop the actor so we'll say CTX state and get our WebSocket and we'll say you send disconnect we'll send a disconnect message to our web socket actor and then we want to send in our unique user ID to kill it from the hashmap and then we can call running stop which will actually stop the execution of this actor all righty so that's that's it for the actual actor implementation but now we need to create the handler so that we can actually receive and send messages between this actor and our other actors so let's go down here and do it so implement handler let's a message for session and actually before I proceed let me check the chat so 10 seconds for the heartbeat timeout it's just a just a arbitrary time you could really make it anything you want you can make it 15 seconds 30 seconds whatever I'll make it 10 seconds because it's fairly standard to do that if a WebSocket doesn't return after 10 seconds and typically it's dead so anyway so the result in this case is a union type and we need to create the handle function which will take immutable self and it will take in the message which we need access to and then in the context which we're also going to need access to you which will be immutable stop context like that and we're not going to return anything because we need to return a union type and all we're really gonna do is just call context text call sir a JSON to string and then pass in our message and unwrap this and essentially what we're doing here is just using sir a JSON to take our message model convert it into a JSON string and then pass it along to our other actor you so when this session receives a message it converts it into JSON and then it passes it along that's basically all that happens alright so now we want to implement what's called the stream handler and so this is essentially a it's sort of like a handler except it allows us to pass more than one message to our actor at a time so this thing stays open for a while so stream handler will take in a message and then a protocol error for a message or a protocol errors will be passed through our stream and we want to implement this first session so you can see here it says it's it's just a trait that allows us to handle a stream in a similar way that that you would hand normal actor messages so it's it's basically the same as what we're doing up here with these handlers but instead of just one event at a time we're sending in multiple events and we need to handle all of those events so and then of course our message type here is the just the generic message that can be sent to this actor it can be any of our messages really as long as we define them about which we did we defined specifically defined that we want to be able to send in this type of message and yeah so that's the only message that we can send to this actor so just our model message type so we're also going to create a handle function here for this and let me is copy this handle function here this part here save a lot of time and this has got to change so the message being passed in here is just a generic message type or rather a generic WebSocket message and basically what we want to do is match on that message and find out what kind of message is coming in here so we have message ping-pong binary closed and text we need to handle all these so specifically we want to worry about the ping type and we're also going to worry about the clothes type and also the pong type of message pong don't really care what's coming through the pawn let's see this is one thing that I don't like about Visual Studio code they don't have a good way to just implement all the branches of a match statement for rust be nice if that was a feature binary let's see we also need clothes I think it's the last one yep so close again we don't care about what's in it all right so if we're ping ping means the message is I believe this is incoming and then pong is out coming so think of it like a ping pong essentially so ping is an incoming message we get self one we create that instance like like instant now and then we can call CTX pong to basically create a pong message and then we can pass in the WebSocket message that is coming through this are not the WebSocket message but the actual data that's coming through the WebSocket message to the pong arm here and then for the pong on we're gonna say self 1 equals instance now and and so you can see we're updating the instant every single time a message is being sent back and forth and so based on the ping and pong that's happening in the WebSocket we can then of course have our heartbeat function either drop the connections or keep them running all right so then for text we're not going to do anything for binary we're not gonna do anything and then for clothes we can just call CTX stop which will stop the the actual actor so if we get a clothes message in the websocket then we just want to stop the actor and that's what this does all right so I think that should be about it for the session see seems about right you guys have any questions about any of this code yet before I move on to the handlers you I'll give you guys a few seconds to think of any questions if you have any you and while you're thinking up those questions I'm going to chuck my cat out of my room again because he keeps ramming in and annoying me you you [Music] all right sorry about that all right I don't know man questions I don't know sorry that's fine man what am I making we're making a chat application using act X so all of this is built with sockets we're about to create the handlers so that this will interface with the web so that we can actually use HTTP requests to send JSON back and forth and then of course we'll have a WebSocket as well and then in another tutorial we'll add or eventually add the front-end probably with flutter or you know maybe I'll make like a angulardart tutorial as well to go along with it I don't know I haven't really thought that far ahead clothes on this so I'll move on to the handlers if you guys do have questions go ahead and feel free to ask them if you have any comments too if any feedback or anything like that I go ahead and ask as well feel free to just leave it in there so let's start with our hand learned on our NS we're gonna put this outside of our actor folder and of course we need to make it into a sub module and you know I hate that I hate that bug so annoying there we go so you can avoid the bug if you keep your imports in roughly alphabetical order but sometimes it can still happen it's really annoying how much of this have I already written out I've written out none of it this is all live coded I just kind of went through the app that I was building yesterday a lot of it is very similar to what we're building today the only major difference is the session WebSocket the session actor and and of course like the model and stuff was different yesterday we were implementing a blog application and I ran into a few snafus with the stream so I decided not to finish it and later after the stream had gotten down I went back through the code and and sort of fixed it and then I went back through the documentation so that's why we haven't run into any errors and I'm hoping that we don't run into any huge ones today I wouldn't mind running into some small ones just so that I can show you guys what's going on here but yeah okay let's import from our actors our DD we're going to need our form type and then our user type and why am i using import wrong language one of the downsides of being a polyglot programmers that we often mix up languages we also need our model the appstate specifically for this one and what do we call it sit session or sessions session night in that's why I want to forget some errors once I do this let's see it's very likely that we will and I'd be surprised if we don't yep we get some cool alright you get to see me debug some of these errors so in the airs we've got here mostly to do with this WebSockets let's go and check these out and see what's going on I think the issue here let's see now it's because the model app state is private I just need to make it public yeah it's not really an interesting no app state is public so that's strange oh it's it's not the model itself it's the it's the fields in the mall I didn't make these properly that's why we're getting these errors and that should solve all these errors there we go not sorry that was more interesting all right so back to the handlers we're importing app states and we need to import let's see what what else do we need I'm going to need AK Tex web trying to do this alphabetically but we'll see we're going to need the error type the WebSocket library async responder future response HTTP requests and the HTTP response type also need JSON and states that should do it and your responses capital and once add another comma here well that's really knowing it I'd rather it put it on two lines but apparently it doesn't want to do that you know what let me commit all this to github so that you guys can take a look at it you you all right so now that should be in github and you guys can go to the link in the chat and check it out her in the description and check it out if you want to keep following along alright so imported act X web good we're also going to need I think futures our future library the future tight and we'll need the UUID of these we might need chrono as well duration this should be there all right so all right we want to create handlers and these are the essentially just the handlers that allow us to interface with HTTP or WebSockets okay well I actually I've got some questions here so let me answer these questions before I finish this up so they lead Duke banal says thank you for your Russ content great value to the community well thank you he says a reason to use act acts of a rocket um so act X does have a history of unsafe abuse the main reason I'd say is that act X uses the actor model so your applications are more distributed since you have actors actors are essentially just processes that get spawned by a scheduler in this case an arbiter and the scheduler and the actors contain all the state of the application and they also can execute all of the all of the Alexa calls all of the logic of the application as well and they can do it you can spawn multiple instance of each of these actors to scale out your application which makes it infinitely scalable any plans to cover the new async FN syntax well unfortunately a weight and async are not currently in rust I did just watch a talk on async await the other day that was fairly interesting I'm pretty excited about the new futures that are coming to rust when that does come out I will be making a formal tutorial about it because it's definitely different than a lot of the other future implementations in other languages in rust futures are implemented with a polling type a polling format rather than a callback format and I think actually the future library uses that same implementation let's see all right yeah so they've got a function here called Paul and what Paul does is it it actually goes in it so the future the future sends back a basically a shell a shell type that future and then when the actual asynchronous code executes you get the value back inside of this shell type with the normal programming language or with most implementations of futures and programming languages like JavaScript or dart you have some kind of callback setup where when the future comes back at call back function gets executed with rust however the way it works is you've got this loop going on in the background and in the loop the application is constantly asking and this will be on a separate thread of course constantly asking to see if that data is ready and it does this through this polling function and then once the data is ready it serves it through a I think it's a response type I'm not sure a response type in an enum and by doing it this way it's got a completely zero cost abstraction which is pretty cool and so it sort of fits in with the rest of the dart of the rust language and it keeps everything pretty light it means you could even use futures and await async if you were writing something like an operating system so and that's pretty cool in my opinion all right so let's get back to this so let's create a login function so this would be a function that gets called when the user goes to a the login route of our application and or pass in the user and then the state and the user will be a jason of user type and then this state will be state with our app state inside of it and this is just a little helper type that we can use to access our state and then we're going to return a future response and this is actually a future and if you see the type here is actually a convenience type so it's just a box with a future inside of it and then with the item I but the item I being the the type that we want to return and I in this case will be an HTTP response type so when the user accesses this route of our application will return our response and yeah we we of course need to have the logic to have the user quote unquote login when they go to this login route so what we'll do is we'll use our estate then need to type it their state and we'll get the database out of this state and then we can call send here to take the user and we can call into inner to then put that into send and into inner just d-structs the inner value of the user in this case we're unwrapping it from this JSON so we're just getting a user struct from JSON then we need to use from error from error let's see if it'll come up that's not gonna come up on show you guys later then after from air we can then use and then and then we have a little closure here which will match on the response that we're getting back here so this is this part is dealing with the future and then we have sort of a callback here with this end then call um and as you can see here it says execute another future after this one is resolved so we have a future up here we resolve the future and we map that future using this the we mount the error here and then we are going to resolve the future with this callback here and I know I just mentioned that futures and Ross don't use callbacks but they've sort of added this abstraction here the end then composing function on to them so that you can add callbacks but you don't have to anyway at least you won't have to once they add a weight and they sync to the language so anyway so when a user logs in with their JSON the response that we get back is a vector of messages and so when we get back that response we want to take that vector messages and unwrap it from the response and then put it back into an HTTP response of type okay and put it into the JSON that's connected to that type that should be lowercase JSON so that it gets served back out to the browser or to whatever front-end we're dealing with then if we have an error type we'll just say ok HTTP response and this will be an internal our status is it without internal server error and we can even attach some JSON to this and I'll just put a little string this is internal server error like that and then of course that will wrong let's make it a little bit more readable and then finally we want to add a call to responder here and we'll remove this semicolon let's see where that clear up the air here should there we go so the responder just converts to a boxed future so we just are making a future here with the end then function and then we need to put it into a box pointer there's a very technical reason why we're actually putting our futures in box pointers and I'm not really going to get into that if you do want to learn more about it than I recommend watching the recent talk on a weight a sync where he does discuss why future

Original Description

#tensorprogramming #rustlng #actix In this Live Stream, we will be building a web application using Actix and Actix_web. We will look into building the application and consuming it with a flutter application. Source Code: https://github.com/tensor-programming/rust_actix_live_stream Request Form: https://goo.gl/forms/rFjHcZMRJ3bYPEC03 Feel free to Support the Channel: Patreon: https://www.patreon.com/tensor_programming Check out our Twitter: https://twitter.com/TensorProgram
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Tensor Programming · Tensor Programming · 0 of 60

← Previous Next →
1 NodeJs, Text editors and IDEs
NodeJs, Text editors and IDEs
Tensor Programming
2 Vanilla JS todo App
Vanilla JS todo App
Tensor Programming
3 Elm Tutorial part 1
Elm Tutorial part 1
Tensor Programming
4 Elm Lang Tutorial, Part 2
Elm Lang Tutorial, Part 2
Tensor Programming
5 Elm Tutorial Part 3
Elm Tutorial Part 3
Tensor Programming
6 Elm Tutorial Part 4 -- Analog Clock App
Elm Tutorial Part 4 -- Analog Clock App
Tensor Programming
7 Elm Tutorial part 5 -- Snake Game
Elm Tutorial part 5 -- Snake Game
Tensor Programming
8 Elm Tutorial part 6 -- Calculator
Elm Tutorial part 6 -- Calculator
Tensor Programming
9 Go Tutorial part 1 -- Hello World and Static File Server
Go Tutorial part 1 -- Hello World and Static File Server
Tensor Programming
10 Go Tutorial part 2 -- Web Crawler
Go Tutorial part 2 -- Web Crawler
Tensor Programming
11 Go Tutorial Part 3 (Web App part 1)
Go Tutorial Part 3 (Web App part 1)
Tensor Programming
12 Go tutorial Part 4 (Web tutorial part 2) - Using templates
Go tutorial Part 4 (Web tutorial part 2) - Using templates
Tensor Programming
13 Go tutorial part 5 (web app part 3)
Go tutorial part 5 (web app part 3)
Tensor Programming
14 Go tutorial part 6 (webapp part 4)
Go tutorial part 6 (webapp part 4)
Tensor Programming
15 Go tutorial part 7 (web app part 5)
Go tutorial part 7 (web app part 5)
Tensor Programming
16 Go tutorial part 8 (Web app part 6)
Go tutorial part 8 (Web app part 6)
Tensor Programming
17 Go tutorial Part 9 (web tutorial part 7)
Go tutorial Part 9 (web tutorial part 7)
Tensor Programming
18 Go tutorial Part 10 (web app part 8)
Go tutorial Part 10 (web app part 8)
Tensor Programming
19 Go tutorial Part 11 (Web app Part 9)
Go tutorial Part 11 (Web app Part 9)
Tensor Programming
20 Go Tutorial Part 12 (Web app Part 10)
Go Tutorial Part 12 (Web app Part 10)
Tensor Programming
21 Go Tutorial Part 13 (Web app Part 11)
Go Tutorial Part 13 (Web app Part 11)
Tensor Programming
22 Looking at Elm 0.18
Looking at Elm 0.18
Tensor Programming
23 Go tutorial Part 14 (Web tutorial part 12)
Go tutorial Part 14 (Web tutorial part 12)
Tensor Programming
24 Go tutorial Part 15 (Web tutorial part 13)
Go tutorial Part 15 (Web tutorial part 13)
Tensor Programming
25 Go tutorial part 16 (web app part 14)
Go tutorial part 16 (web app part 14)
Tensor Programming
26 Elm Tutorial Part 7 (SPA part 1)
Elm Tutorial Part 7 (SPA part 1)
Tensor Programming
27 Elm Tutorial Part 8 (SPA Part 2)
Elm Tutorial Part 8 (SPA Part 2)
Tensor Programming
28 Electron Elm Tutorial
Electron Elm Tutorial
Tensor Programming
29 Go tutorial part 17 (web app part 15)
Go tutorial part 17 (web app part 15)
Tensor Programming
30 Up and Coming Programming Languages and Technologies for 2017
Up and Coming Programming Languages and Technologies for 2017
Tensor Programming
31 elixir tutorial part 1
elixir tutorial part 1
Tensor Programming
32 elixir tutorial part 2
elixir tutorial part 2
Tensor Programming
33 Elixir tutorial Part 3 (GenServer and Supervisor)
Elixir tutorial Part 3 (GenServer and Supervisor)
Tensor Programming
34 Elixir Tutorial Part 4 (GenStage)
Elixir Tutorial Part 4 (GenStage)
Tensor Programming
35 Elixir Tutorial Part 5 (Plug and Cowboy)
Elixir Tutorial Part 5 (Plug and Cowboy)
Tensor Programming
36 Phoenix Framework Tutorial Part 1 (elixir part 6)
Phoenix Framework Tutorial Part 1 (elixir part 6)
Tensor Programming
37 Phoenix Framework Tutorial Part 2  (elixir part 7)
Phoenix Framework Tutorial Part 2 (elixir part 7)
Tensor Programming
38 Phoenix Framework Tutorial Part 3 (elixir part 8)
Phoenix Framework Tutorial Part 3 (elixir part 8)
Tensor Programming
39 A Intro to Clojure and Clojure Syntax
A Intro to Clojure and Clojure Syntax
Tensor Programming
40 An Update about the channel
An Update about the channel
Tensor Programming
41 Intro to Rustlang (Setup and Primitives)
Intro to Rustlang (Setup and Primitives)
Tensor Programming
42 Intro to Rustlang (Strings, Tuples, Arrays, Slices and Pretty Printing)
Intro to Rustlang (Strings, Tuples, Arrays, Slices and Pretty Printing)
Tensor Programming
43 Intro to Rustlang (Ownership and Borrowing)
Intro to Rustlang (Ownership and Borrowing)
Tensor Programming
44 Intro to Rustlang (Structs, Methods, Functions, Related Functions and the Display/Debug Traits)
Intro to Rustlang (Structs, Methods, Functions, Related Functions and the Display/Debug Traits)
Tensor Programming
45 Intro to Rustlang (Control Flow, Conditionals and Pattern Matching)
Intro to Rustlang (Control Flow, Conditionals and Pattern Matching)
Tensor Programming
46 Intro to RustLang (Enums and Options)
Intro to RustLang (Enums and Options)
Tensor Programming
47 Intro to Rustlang (Vectors, HashMaps, Casting, If-Let, While-Let, and the Result Enum)
Intro to Rustlang (Vectors, HashMaps, Casting, If-Let, While-Let, and the Result Enum)
Tensor Programming
48 Rustlang Project: Snake Game
Rustlang Project: Snake Game
Tensor Programming
49 Intro to Rustlang (Traits and Generic Types)
Intro to Rustlang (Traits and Generic Types)
Tensor Programming
50 Intro to Rust-lang (Closures, the Box Pointer and Iterators)
Intro to Rust-lang (Closures, the Box Pointer and Iterators)
Tensor Programming
51 Intro to Rust-lang (Modules and Lifetimes)
Intro to Rust-lang (Modules and Lifetimes)
Tensor Programming
52 Intro to Rust-lang (Macros and Metaprogramming)
Intro to Rust-lang (Macros and Metaprogramming)
Tensor Programming
53 Intro to Rust-lang (Error Handling)
Intro to Rust-lang (Error Handling)
Tensor Programming
54 Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
Tensor Programming
55 Intro to Rust-lang (Tests, Attributes, Configuration and Conditional compilation)
Intro to Rust-lang (Tests, Attributes, Configuration and Conditional compilation)
Tensor Programming
56 Rustlang Project: Port Sniffer CLI
Rustlang Project: Port Sniffer CLI
Tensor Programming
57 Rustlang Project: Chat Application
Rustlang Project: Chat Application
Tensor Programming
58 Rustlang Project: CLI Toy Blockchain
Rustlang Project: CLI Toy Blockchain
Tensor Programming
59 Intro to Rust-lang (Setting up a Development Environment)
Intro to Rust-lang (Setting up a Development Environment)
Tensor Programming
60 Intro to Rust-lang (Building a Web API with Iron)
Intro to Rust-lang (Building a Web API with Iron)
Tensor Programming

This video teaches how to build a web application using Actix and Actix_web, with a focus on live coding, chat application development, and database interactions using Postgres and Diesel. The video covers various topics, including HTTP handlers, WebSockets, and actor-based systems.

Key Takeaways
  1. Set up Actix and Actix_web for building a web application
  2. Create HTTP handlers for login and message sending
  3. Implement WebSocket handler for live updates
  4. Use Postgres database for persistence
  5. Setup Flutter application as a separate live stream
  6. Derive traits for serialization and deserialization using Serde
  7. Implement actor traits for DB actor type
  8. Define execution context for DB actor
  9. Implement message trait for DB actor
💡 The video demonstrates how to use Actix and Actix_web to build a web application with live updates and database interactions, showcasing the power of actor-based systems and WebSockets.

Related Reads

📰
What Is MLIR and Why Does It Exist?
Learn about MLIR, a intermediate representation for machine learning models, and its purpose in optimizing ML workflows
Dev.to · Fedor Nikolaev
📰
Why Choosing the Right Machine Learning Development Company Matters More Than the AI Model
Choosing the right machine learning development company is crucial for turning AI investments into measurable results, as it can make or break the success of AI projects
Medium · Machine Learning
📰
Data privacy in AI training: federated learning, differential privacy, and synthetic data
Learn how federated learning, differential privacy, and synthetic data preserve data privacy in AI training, and why they matter for secure machine learning
Dev.to AI
📰
Data Preprocessing: Encoding and Feature Scaling in Machine Learning
Learn to preprocess data by encoding and scaling features for better machine learning model performance
Medium · Machine Learning
Up next
Is Python Dead in 2026?| Truth About Python in AI Era | 90 Days Roadmap @FameWorldEducationalHub
FAME WORLD EDUCATIONAL HUB
Watch →