When you find yourself in a polling situation (like wishing you knew when something changes) it's time to turn to events. What are events? Well at the heart it's polling, done better.
Let's say you have ten things that enter the database that you wish you knew the minute they changed. You could hit the database ten times a minute. Or you could just query once a minute.
This is how interrupts work in your computer's architecture. One register with many bits is checked in a tight loop each clock cycle. If any bit is non zero something is interrupting normal program flow and waiting to be dealt with. Which bit tells you what's waiting.
Done at the database level this scheme could be done with a string. Considering query overhead a reasonably sized string should perform nearly as well as an int. So keep a time stamped table of named events. It works like this:
- Query the table for events newer than your last check.
- Delete events older than your last check.
- Deal with events (query whatever needs to be queried)
The order you feel like putting that in has more to do with debugging than performance.
You'll need some way to create events in the event table. That could be done in the db itself or it can be done in whatever updates the db. When you update the Foo table you could also drop a timestamped Foo string in the event table. When you delete the Bar entry from the Baz table you could drop a timestamped Baz-Bar string in the event table. It's gloriously asynchronous and scales very well. 10, 100, 10000 kinds of events load the db the same way.
Now you know when a cached value is out of date so you can update it timely.
If you're not the only one watching these events deleting gets a bit tricky. It is possible to come up with a scheme to register observers of events and only delete them once everyone has consumed them but that's brittle. One observer goes down and the DB is filling up. Better to define a window of time that events will live for and delete ones that have left the window.
Of course all of this could be avoided if you could find a way to use an alternative to the DB such as a messaging system. Make no mistake, this is a hack. It's a hell of a lot better hack than polling everything individually but it's still a hack.
CachedQuerier(NormalQuerier)
, else you instantiate just aNormalQuerier
. The process is completely transparent to the rest of the application, which doesn't care if the value is cached or not.