tag:blogger.com,1999:blog-27876765.post4441813458752169140..comments2024-03-20T13:37:39.909+01:00Comments on Day to day stuff: Asynchronous cache updatesErik van Oostenhttp://www.blogger.com/profile/15976519439979651010noreply@blogger.comBlogger2125tag:blogger.com,1999:blog-27876765.post-2521709308099591312008-08-18T19:26:00.000+02:002008-08-18T19:26:00.000+02:00Jurjan-Paul! Nice to hear from you.You are complet...Jurjan-Paul! Nice to hear from you.<BR/><BR/>You are completely right about that the control flow of PeriodicExecutor can make you serve very old stale data in some circumstances. As with any caching/mirroring solution (nice distinction) you must make sure that these circumstances do not, or rarely occur and whether this is acceptable at all.<BR/><BR/>Regarding the fact that the client can not see that there is a synchronization problem, this can both be a blessing and a big problem. I agree that for currency exchange rates this is rather undesirable. On the other hand, I have also seen that a site remained running while someone had changed the database and the postal codes were no longer available. This was found quickly because the logs were monitored. The solution took a couple of days but meanwhile the site just continued working properly. So again, you must make sure you can live with stale data.<BR/><BR/>One way to make the alleviate the problem a bit is to update the cache synchronously when some unacceptable timeout has been observed. It should also not be very difficult to add the option to rethrow any failures when the retry failed.<BR/><BR/>Regarding code ownership: this code was created way earlier, and in my spare time.<BR/><BR/>In conclusion, I find calling PerioidExecutor flawed a rather too strong statement. There are many valid use cases, including your code base :) Still, the extra warning is appreciated.<BR/><BR/>Regards,<BR/> Erik.Erik van Oostenhttps://www.blogger.com/profile/15976519439979651010noreply@blogger.comtag:blogger.com,1999:blog-27876765.post-81007521510481937642008-08-18T17:26:00.000+02:002008-08-18T17:26:00.000+02:00Erik, how are you doing?Thanks for sharing your ex...Erik, how are you doing?<BR/><BR/>Thanks for sharing your experiences and making me think once more.<BR/><BR/>After reading this piece, chewing on it for a while and indeed discovering your 'PeriodicExecutor' class in our code base (what does that say about code ownership?) I must say that I think your 'solution' is conceptually rather flawed.<BR/><BR/>For reasons of apparent 'premature optimization' - What's wrong with an idle thread if it serves a well understood purpose? - you have tried to compromise two pretty well understood modes of operation (1. a traditional cache that only fetches data when not cached already or invalidated e.g. because of expiration; 2. a mirror that gets periodically synchronized in the background) and seem to accept the risk of incorrectness as if correctness should not be the number one requirement.<BR/><BR/>When given an expiration timeout, both a cache and a mirror provide a pretty good guarantee that no expired/invalidated data is ever served. Failure is obviously always an option (no connection or whatever), but will get noticed and marked clearly. Depending on the kind of data and how it is used, such a synchronization problem will need to be considered fatal or not by the client.<BR/><BR/>Your 'Asynchronous cache updates' idea happily serves expired data, both in the normal case of data being requested for the first time (long) after it has expired and in case of synchronization problems. Despite some complexish Exception handling (automatic retries usually have little chance of succeeding and make problems even harder to diagnose), you are effectively eating them. As a result the client application has no way of knowing that it gets served expired data. For a list of postal codes that gets used all the time, this might not be problematic, but in the general case I really don't see how this behaviour can be acceptable in light of any 'real (business) requirements' (quick attempt at examples: fetching a Certificate Revocation List, currency exchange rates, etc.).<BR/><BR/>You do mention Quartz and I would say that using that for background synchronization would be a much better choice in most situations.<BR/><BR/>In the mean time we're happy to have established that at least the way PeriodicExecutor is used in our code base, it won't do much harm... ;-)Jurjan-Paul Medemahttps://www.blogger.com/profile/17311716656988176266noreply@blogger.com