Get caught up:
Part 1: http://randomgoo.blogspot.com/2012/02/release-event-hub-web-30-introduction.html
Part 2: http://randomgoo.blogspot.com/2012/02/events.html
Part 3: http://randomgoo.blogspot.com/2012/02/event-listeners-get-up-to-speed-first.html
Part 4: http://randomgoo.blogspot.com/2012/02/event-hub.html
Quick recap - Web 3.0 is two-way asynchronous programming - events on the way out and another event or a callback on the way back.
An oft overlooked key piece to any application is its deployment. Deploying a 'traditional' HTTP-server based application is a one-shot all-or-nothing affair. Typically even the smallest server-side change requires a full-blown deploy and restart of all of your HTTP servers. Well that blows.
Compare with an event-based application consisting of a federation of independent processes that comprise the application. You only need to deploy and restart small, independent pieces of the application for updates, not the entire thing.
Now it's not all wine and roses (or beer and dandelions). There is more complexity because there are more pieces. But small and independent beats large and monolithic even with the extra complexity, of which there isn't that much.
But the biggest issue is dropping events. HTTP servers have 'graceful' shutdowns, ensuring all current requests are satisfied before shutting down, ensuring remote clients aren't left in the lurch during a restart, what about Event Hubs?
Glad you asked, let's look at the scenarios:
Server Side
1. Broadcast events
Broadcasted events are sent to every connected module. Each broadcast event listener should listen for a signal or other outside data that tells it to shutdown. So to shut down and restart a broadcast event listener, simply bring up the newer version of the listener and tell the old one(s) to shutdown.
Like a 'graceful' shutdown the current about-to-be-shutdown listeners should immediately stop listening for the given event, wait until they are done servicing any existing events, and then shut down if that is the only event that module is listening for.
Here is where putting a version number in the event name is also useful. If using this method bring up the new listener that listens for the new event name with the updated version number and update the clients to use this new event name. As clients start calling the new event name (with an updated version number in it) the old listeners duties trickle away until it can be safely killed.
2. Unicast Events
This is even easier as the event hub notifies the old listener (via an event) when a new one takes over that it has been replaced and can stop listening for the unicast event. At that point the listener will finish with any current events its dealing with and then shut down.
So you need only the bring up the newer version of the unicast listener, it will connect to the hub, telling the hub it is the new listener for the given unicast event. All subsequent unicast events will get passed to the new listener and the old listener will receive a event from the hub telling the old listener that its work is done.
Client-Side
The above two scenarios detail how to shutdown old server-side listeners, what about updating clients? Welp that is no different than what we currently do when we roll out new client-side web application code: push the code out the the CDN. Your HTTP server is still around to server the static client-side code. Subsequent browser refreshes will now get served this new code. Same deal.
What is more interesting is the client-side code is split into many smaller individual files which can be changed independent of all the other files. It's not quite as clean as that because for efficiency the small Javascript files would be mashed into one large one and then minified for performance, regardless the process is the same as for current web applications.
Deploying small changes in client-side code is a very interesting topic and I hope someday to learn how to do it better...
The Hub
What about the hub itself? The time will come when it needs to be restarted for whatever reason. The best way is to bring up a new hub and bring up another set of listeners that connect to it. Update client-side code to point to the new hub and push it out. Wait. Wait some more. Eventually traffic to your old hub will cease, then you can shut it down and shut down all the listeners connected to it.
When is safe to shut down the old hub? Where there is no more client traffic! We'll look at that in the 'Logging' post coming up soon!
I hope you can see deployment of event-based asynchronous application is more complex because there are more pieces but much more fine-grained and much safer overall.
Stay tuned for Logging, languages, and an implementation!
No comments:
Post a Comment