Many years ago we wrote a “multi-threaded-ish” client/server reports generation system.
It was based on VB6, SQL Server 7, Crystal Reports 7 and MSMQ on a mixture of NT4/Win2K/Win98
It had multiple EXEs running on the server (multi-threaded-ish), listening for round robin requests from client for reports to be generated and messages sent back to a tray-app on the client machine.
This all worked very nicely until MSMQ became a pain to support and we ditched it for single-threaded reporting on the client machine.
Now we have to re-create that system using modern tech.
So:
- SQL Server 2005 onwards
- Win Server 2003 onwards
- .NET 3.5 (yes, I know, not that modern)
- A “web front end” (irrelevant as all the IPC is server side, albeit on multiple servers)
- Crystal Reports 10.5
Now, mostly, nothing there is difficult.
But after being burnt by MSMQ, we want something that can be deployed without a hundred different customer IT policies making it impossible to support.
My default fall back in this position is simple. Use SQL Server to store a list of jobs and the status of those jobs.
We all ready have a “ReportLog” table to store the jobs, I’d just have to add state fields to it, probably:
- Running (bit, not null)
- Complete (bit, not null)
It’s dumb, simple but will work.
My Dumb Solution
OK, so I build a windows service that has one thread watching the table, spawning thread pool jobs each time a new job appears. Each thread will return OK or Error on completing it’s single report and die.
Client scan the Log table watching for jobs to complete.
Advantages:
- It will always work, no IT department will get in our way
- It’s simple, everybody will understand it
- No extra technology or config. (MSMQ always needed installing and configuring)
Disadvantages:
- Client has no idea about the status of the service.
- It’s double passive, both client and server constantly polling a table
- If multiple servers are started up, they’ll start double rendering reports
- Only solution for (3) I can think of is some sort of exclusive write lock on the table (Yuck!)
- It feels like square peg in round hole, a workaround rather that a solution. IMO this isn’t what databases are for!
Question 1: If My Dumb Solution is a good idea, how can I prevent Disadvantage(4)?
Question 2: Seriously, isn’t there something better that MSMQ and SQL Server table polling? Something that has at least Advantage(1) and (3)
If you’re already using SQL Server, then SQL Server Service Broker is your best replacement for MSMQ, especially for this scenario.
Disadvantages #2, 3, 4 and 5 are resolved automatically, and #1 is resolvable with some work. You should be able to retain Advantages #1 and 3, but will probably lose #2.
I have implemented several service-based solutions this way, and specifically you want to use the External Activation approach, also called Event-Based Activation.
The documentation states: