 Hello and welcome to bonus round number two also known as give the people what they want in bonus round one I showed you that we added notifications to the site And I said yeah Just let me know if you want to see the back-end code and virtually every comment in YouTube was like shows the back-end code Now Okay. All right. Well far be it from me To prevent you from seeing the code you wish to see At the moment the code is not on github, but who knows by the time this goes out it may well be I just needed to do a bit of tidy up and just generally Look through it and just make sure there's you know Nothing in there like there's I'm sure you can imagine. There's things like a Wharf secrets and stuff like that for actual Authentication, so I just need to make sure that none of that's actually gonna go out Unexpectedly So it might just take me a little bit longer to just get through that because I do actually have a bunch of stuff on at The moment. There you go. Excuses come as standard Right, let's look at some code since that's what we're all here for That's a really good little motion Right, okay So the thing about the server side of sending push notifications There's two parts that you need to sort of think of firstly. There's the the master And then there's the workers Probably in correct terminology. I would call them slaves, but there we go. I'm calling them workers so you can see on screen I have the Index that the thing is actually going to run first of all and it uses nodes cluster Module which is really helpful in the situation and what it does is the first Process the first node process to run this code will be considered the master and so I assign it the the role of master and Then the everybody else is assigned the role of worker And you'll see what that means in a moment So basically I require in whichever role you've been given and then I tell that one to in it So both of these modules the master and worker both have an in it so I can just call it and it'll be fine so let's look at master first of all master is Has Really kind of two jobs one is to spin up an express server so that there's an admin interface Which looks like let me show you that looks like this And you can see that we've got all the the various sessions And then there's the generic I want to send an event updates It's not the prettiest thing in the world, but it'll do the job just fine and dandy So it spins that up as an express server And the other thing it does is it maintains a list of all the messages that need to be sent So in the back end when we click on the button and I'll show you the code for this in a moment We click on the button that says okay tell everybody the keynote starting It puts the this here actually you can see this in queue here pushes the task onto the task list and it will wake up the workers to go and actually do that work and we'll come back to that in butter moment so most of this is Not that exciting perhaps let me just say I'm where where's where's a good place to add of it the in it You know in it that I called it creates the workers as needed Which we'll have a look at in a moment and also in it's the server so the create workers as needed function is here and I Basically look through the number of existing workers which at the start will be zero and then I figure out the total work account Minus the number that we've already got so if the work account is right up at the top and it's based on the number of CPUs available That means that if I say have a machine with eight cores I take one off the length so I basically assign one CPU to being the master and Running the express of and then the remaining seven would go to running workers If I had 32 cores 32 CPUs it would be 31 for the workers and one again for the Process the master and I I default it to four so there's even if I have a machine with one CPU I'm just going to run four Workers and then one so at least a minimum of five node processes So that's how that works Let's have a look at the server code because there isn't I mean most of it sort of What you'd expect it's kind of? Standard express stuff although what I do Right at the start. Where are you? I actually load the sessions Jason from the site and and I pass that through to the admin renderer in order to actually Where are you right in the admin section to actually render the admin so I get the sessions and then I render the The admin section with that and then that just that's just handlebars just stepping through those objects All works just fine when we actually send a Message, let me go into the code for that. This is in the subscriptions area Yeah, it's the it's ping and it takes the keys Which is done here? Yeah, I'm using the web push library Which will link to in the notes I said that in the last episode and I don't think we did but I think we will this time I'm using the web push library from node and you can ask it to generate vapid keys vapid is the cross browser Encryption keys that you need if you're going to send a payload to devices and it means that you can deal with Google cloud endpoints if your subscribers are using Chrome or A Mozilla endpoint if they're using Firefox and vapid is the cross browser way of you know Encrypting your payload and so you want something really that generates vapid keys for you because doing encryption on your own is not that much fun And this does it for me so I can create vapid keys and the other thing you'll see around the code here Is there's this DS which is the data store? I'm using a Google cloud data store to store all the keys and the Subscriptions and everything else you could just as well use my SQL you could just as well use MongoDB whatever back-end data store you would make sense in my case I'm running on Google clouds or why not use that makes perfect sense, and it's very convenient for me so When we do a ping we've already got the keys because I generate those once at the start and I store those in the data store so that I'm not generating new keys every time you want to have the same keys keys the ID is the It's the slug the dev summit slash schedule slash keynote blah blah blah Because when we're in the back end we can sort of send To you know though say for example those people and so that the ID that target if you like is Those the message that we want to send will be the same thing actually mostly likely be the slug or it could be if it's the General send an event update. It'll just be some free text or some emoji or whatever it needs to be And then there's a link back to the master so I do a kind of dependency injection when I in it the server You'll notice here. I pass in a reference to master here so that it can It can ping back. Okay, so for argument's sake. Let's say we've got a thousand endpoints registered okay across a whole range of sessions this Retrieval filters them down by those who just want to say get the keynote or just get Jake's session on the future of service worker stuff So we filter those down and we get back a bunch of endpoints and for each of those endpoints As I mentioned earlier, there isn't an queue function in the master and we pass through both the keys the endpoint and Description and the actual message that we want to send and then in my case. I also log the number of People or the number of endpoints that we've pinged So I come we can see in the back end Oh, this one definitely went to like 300 people or it went to however many people. I don't know how many it's gonna be Right so the master and queue I mentioned it before It's put all it does is it pushes the task onto an array. So the master has this global Array of messages that need to be sent it steps through all the workers that were created and It pings them. It's just sends this ping message which will cause them to wake up and Then there's a bit again. There's a bit of logging for me just to kind of go with the job started Yeah Right now we get to talk about the workers there on the other side of this So as I said our master is it's got two jobs One is to maintain this this queue and when we send we just basically we populate this queue So we let's say We had a thousand endpoints a hundred people wanted the keynote So we'll fill this array and it'll have a hundred entries in it at this point and we ping the workers to wake to wake up The on message is where that then kicks in if it gets a ping and it is sleeping It wakes up and we call process.next next tick process.next tick which is kind of like Set immediate or set time out zero, but it's a bit. It's proper neat and tidy. It's not set set time out zero It's actually like though There's a it's the proper node way of doing it is the best way to say and they've optimised It's not just like set time out zero. It's properly done apparently To call this request task. So the request task where are you is up here All that does is it calls this send function, which you can see Basically posts back to the master and says I want a task, please So the the master has woken them up each of the workers is going to come back to the master and say I want a task, please Which you can see down here on the on worker message if they say I want a task, please We pop one off the end. So you Strictly speaking might want to unshift and take the front of the queue I don't I just pop the back off the queue. I'm hoping it you know Doesn't matter really ultimately the queue will get depleted one way or another and it sends that back to the worker It says here's a task for you one task off you go and do it so the worker will When it's got a task. Oh, yeah, you see if there is no task for it to do the queues empty The worker goes back to sleep Okay, and we'll wait for the next ping before it tries again, but assuming it gets given a task it sets the vapid keys that it had from way back when and There's also a URL that you give it the I default the TTL to 30 minutes if for some reason the message It's you know Like a session is about 30 minutes I think I don't think we've got any more than 30 minutes if for some reason you don't pick up that message in 30 minutes It doesn't feel right to be like hey the keynote starting now if the key notes no longer running So I'm hoping that that will just mean that the the message will expire and we don't over notify and bug people When they don't need to be bothered And then we call the send notification Which is again a convenience method on the on that library which is brilliant and you give it the subscription Which will contain the endpoint and the key some more keys the message that you wanted to send and if there's any issues at all I just kill the worker and There is a in the master if a worker is killed there. We are on exit On disconnect it will come back and it will try and recreate any any workers. So say for example For whatever reason we had eight workers and four of them were killed Then we'd create four new ones here to kind of replenish and always bring us back up to the correct number So it's it's good and that works just fine as well So what else do we need to show you or do I need to show you in the worker? So hopefully based yes, hopefully at this point We've managed to send a notification and then we go back and ask for another task So as each workers getting to the end of its task it goes back to the master and says have you got any more work for me? Eventually that key will be depleted and the worker will say oh I've got nothing I will go To sleep and it will then wait until it gets the ping from the master saying oh there's a new job for everybody Let's get through this now I like this approach because of the fact that I get to control the number of workers if I Decide to deploy something with 32 cores or 16 cores or 8 cores or 4 cores it means that I get to decide how many workers there are and You know, well, they'll always be one for the the master process But this for me is good because if I feel like this is going to be bursty I could be like okay, just spin up a load of workers and Just they can churn through the queue. They can go at the same time concurrently or parallelized. They're different things They are and I forget the difference in definition Me but they've run at the same time It was splitting the work out and that's that's under my control as to how many of those there are I can just have one I can have as many as I need and that means it works out really well for me So there you go. That is the the back-end code It is in JavaScript for those of you wondering why it's in JavaScript and not in Python There's so that for legacy reasons the site is in Python as and it's always been in Python since I first did it four years ago three years ago, I don't know I guess three years ago and It's just always been in Python and that's not a big deal, but this I wanted to keep separate I wanted it on its own Separate thing as a separate almost service that I can spin up and spin down for Chrome dev summit independently of the site So it felt wrong to me to have something that is both serving the site and handling notifications because if Pushing notifications if it sort of becomes CPU intensive for whatever reason I didn't want to jeopardize the site serving in that process. So it felt like it just kept them separate and that all Works out well for me and the other main thing and it is not insignificant is that the web push library for node is really good It's incredibly convenient and it does the things you need it generates the keys It will encrypt a message for you and it will send it to the endpoint the three things you really need it to do Are the three things it will do just perfectly. So the fact that it's a Well-tested robust library for actually doing the push messaging Combined with the fact that things like Express are really nice as well Just meant it was a very easy fit to do all this bit in JavaScript cool I hope by this point the code is on github if it is you'll be able to find it Probably there'll be a link in the description below Brilliant Who knows if there'll be another bonus round I Don't know it depends on how much more I get done before Chrome Dev Summit itself speaking of which don't forget that you can subscribe to the channel and as the live stream goes live You'll get that notification. You can get actual notifications. We have talked about this before. I don't know if you know But you can get those on the site. So if you want to subscribe to a particular session I don't have any sessions this year But if I did you could subscribe to that but you could subscribe to someone like Jake's he's got a session and I I have It on good authority that it's going to be another good one from him But they're all gonna be good. So you should subscribe to all of them Good, right. Thank you very much for joining me once again. Take it easy. I'll catch you maybe in another one of these