1

I have recently started updating portions of our corporate platform, and I've been trying to find ways to make the entire platform more efficient, better structured, and just cleaner in general. With SignalR finally being pretty well ready for our version of the MVC framework, I decided to get my feet wet with it by attempting to replace polling in certain parts of our application with SignalR notifications. I managed to get SignalR working, but I hit snag during my implementation due to how we had coded some other features of our application.

My main example is our reporting platform. We have an in-house reporting platform built into our application that can run predefined reports with custom parameters. Not to delve too much into the implementation, but we effectively have a ReportRunner class that kicks off and manages the report run. It does this by creating a task on another thread and kicking off an asynchronous task that isn't awaited. This task has the ability to monitor its status and update a database record accordingly. This tracks all runs, statuses, and errors for all report runs.

When a report run is kicked off, the runner returns a GUID to the WebUI and it continues it's work with running the report in a separate thread. The runner is fairly lightweight and short-lived, it's instantiated by a controller action and processes only the report it's handed and then it's destroyed.


My dilemma really revolves around how this report runner is implemented. Since the report runner is a single-use class, once the report is kicked off, we stop tracking it. This has the unfortunate side-effect of us never knowing the current status of the report run without repeatedly querying the database and awaiting a status change. This obviously can have many other potential side effects (reports never completing, wasted cycles, etc), but the main one is that I have no reliable way to notify users that their report is complete without performing some sort of polling, either client-side or server-side.


So the essence of my question boils down to this; what is a good approach to handling notifications throughout your application without having to tie up threads, poll, or loop?

One of my initial thoughts was to create some sort of basic "notifier" or callback, some sort of class that I could pass in as a parameter to my ReportRunner that could alert my WebUI when the report was complete. This also has lead to other theoretical questions such as, how would I actually call a method in my parent class, and what are the best practices around handling these type of problems? Are there frameworks out there that handle this at a larger scale? Is there some sort of variance of the pub/sub or notify/subscribe patterns that I can apply to this?

  • 1
    In short: you need something like a central "event manager" or "event queue" in your application, for certain categories of events, like "report finished". Each report runner sends an event "I am done" to that event manager (including its GUID), and any other component which has subscribed to that event category gets informed about it. – Doc Brown Oct 6 '18 at 6:17
  • 1
    .. how you exactly implement this depends on the technology stack & infrastructrure, but having a short look at SignalR, this might be appropriate for letting the event manager inform your WebUI about such things. – Doc Brown Oct 6 '18 at 6:20
0

To avoid creating something home-brewed, how about creating a windows service which is hosting SignalR. This service can be watching the report table using
SqlDependency and then notifying the client through SignalR once the table has changed.

The MVC application can kick off the process in a fire-and-forget manner, the windows service will be responsible for notifying the client of the result (error or success). Thus it will delegate the notification concerns to the windows service. I think you will be able to slap together a POC in minutes, maybe a few hours, to give it a try.

Since the windows service will be notifying the client, you would need to somehow map the original request which arrived to the MVC app to the response. In case you need to send the response to a specific client, instead of broadcasting to all, use this technique.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.