I have a Windows service that continuously performs calculation tasks. There are multiple calculation steps performed as part of a single calculation task.
This service is required to log/track the calculation tasks and steps so that multiple clients can poll and observe the activity.
To meet this requirement, I’ve added a simple Dictionary<Guid, List<string>> (_activity) to my service that collects the activity messages. The key is a Guid representing the CalculationTask.Id, and the value is a List<string> holding the messages from the individual calculation steps.
I naively added a method to the service that is invoked by the clients (via wcf) to poll for activity messages. The client would pass in a lastPolledTimeStamp in an attempt to tell the service, “give me all of your messages since I last polled“…
private readonly Dictionary<Guid, List<string>> _activity = new Dictionary<Guid, List<string>>();
public List<string> GetActivity(DateTime lastPolledTimeStamp)
{
var snapshot = _activity.ToList();
return snapshot.SelectMany(x => x.Value)
.Where(x => x.TimeStamp > lastPolledTimeStamp)
.OrderBy(x => x.TimeStamp)
.ToList();
}
Here are my problems and questions:
(1) When the client and service are on different machines, attempts to filter the results by date/time comparisons will not work. And I can’t simply return everything in _activity each time GetActivity is called – there’s too much data. There has to be some sort of filtering. What other options do I have?
(2) Another “problem” is knowing when an a key/value pair in the _activity dictionary can be removed. The clients are polling every 5 seconds. I want to keep the key/value pair around long enough so that clients have a chance to pick it up… Perhaps I should include another timer that executes to periodically clean up the old entries in _activity. Thoughts?
For your first problem, return the server’s time with each response, and get the client to send this timestamp, rather than their own time, when making a request.
For the second problem: if the calculations/steps may be producing messages at different rates, rather than have a fixed-size buffer for each set of updates, I’d stick with running a cleanup job every so often, deleting messages older than [a small multiple of the client’s ping interval].