ASP.NET SignalR has been getting plenty of buzz and attention lately in several different circles. Unfortunately, it's often demoed in user groups and online samples as a means of providing chat functionality. Although it's cool to see how easily and efficiently SignalR can be used to whip-up chat applications, I can't help but wonder if a seemingly obsessive focus on chat hasn't sold some of SignalR's strengths quite a bit short. To that end, I've actually been using SignalR to help tackle some really tough problems and have been blown away by how amazing and powerful it has been in letting me address some difficult use cases.
SignalR versus a Data Deployment Application
One of my clients recently came to me to help automate a semi-complex process that they've had in place to manage data modification and deployment needs for their larger e-commerce site. The rough idea of the solution that they've had in place is that their data team modifies product descriptions, keyword text, pricing details, and several different associations in a non-production staging environment.
Within this environment, the data team can validate all changes before they can go live. Updated definitions, associations, and other changes, which weigh in at roughly 40 to 50 million rows worth of data spanning over 60 tables and over 4GB of data, then get pushed out to staging tables in production once the data team's changes have been validated.
To make these changes go live, corresponding product detail tables in the production database are renamed by using sp_rename during non-peak hours. This process effectively makes production tables become 'production_old' tables and corresponding staging tables are spun up to instantly take their place. This provides a means to avoid the kinds of locking and blocking that would occur if these 40 to 50 million rows were first truncated from production tables and then loaded back in.
To tackle the task of automating this push process, I initially thought about using SQL Server Integration Services (SSIS). But as requirements became clearer, I came to realize that SSIS would be a pain to use. For starters, SSIS is incredibly brittle and doesn't suit the need to implement gradual changes where tables and data end up getting staged and deployed into production. Although I initially thought this solution would be used by developers or a reluctant DBA, management determined that a web application that's used directly by the data team would make more sense rather than saddling developers with managing this operation. Although tapping into the SSIS object model from within ASP.NET sites is possible, licensing requirements for SSIS means that we would need to deploy IIS to an existing staging SQL Server or deploy a license of SQL Server to an existing IIS box. Obviously, neither of these options are very appealing.
Ultimately, that left me with several interesting requirements and problems for my web application. Highlights include:
- Unattended Execution. Because this app needs to be accessible to members of the data team, who are assumed to be non-technical members, they need to be able to 'fire and forget' as the engine I built orchestrates changes that roughly moves 50 million rows from one server to another. Once this process kicks off, the web application can't simply terminate because the user who initiated it closes their browser.
- Re-Entrance. Obviously, if users could start gigantic processes and close their browsers, they would also need the ability to reopen this site and pick up exactly where the engine was currently processing. In other words, this application wouldn't pick up where the user left off, but it would pick up where the overall operation had gotten to while the browser was closed.
- Multi-Entrance. Because multiple members of the data team might want to check up on overall push or go live status, or because one member might start some initial processes and another member of the team might end up executing subsequent steps in the overall process, my solution needed a website or UI that would let users join the application right in the middle of processing. Through this process, any user that's connected to the application would see the same thing as other users. More specifically, all users are able to see up-to-date and real-time status of overall processing.
- Complex Guard Rails. Building a solution that lets non-technical users push 4GB of data into production and then rename tables out from under users has all sorts of scary potential written into it. As such, a key component of my solution needed to include a complex set of rules and workflows that could be easily translated into a simple UI that would simultaneously report on current execution details to all connected users. Furthermore, these rules would need to make sure that steps couldn't be taken out of turn, rerun during execution or skipped, and so on.
SignalR to the Rescue
Ironically, the only problem I had getting everything to work was verifying that I could use SignalR to pull off what I wanted to do and finding examples of non-chat solutions built with SignalR. Happily, I came across SignalR-StockTicker, which is a fantastic demo application that perfectly modeled the idea or notion of multiple clients (browsers) interacting with a single, shared, object or process hosted on a back-end server. Consequently, that demo app, along with the documentation found on "SignalR Client Hubs" and "SignalR JS Client Hubs" helped me get up to speed with obscenely less effort than I would have had to expend otherwise. As such, I think SignalR is a fantastic addition to the ASP.NET family. Not only do I see it having great potential for dashboard applications and other complex solutions, but I also can't wait to use it on some other projects that I'm working on as well. Even if none of those applications are chat-focused.