New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proper use of clockDateCacher in scaffolding #15
Conversation
I think forking a separate update thread isn't too complex an operation to include here. Would you be able to update the pull request to take that approach? |
Sure - can't do it for a few hours now, but it's easy enough (it's one of the variants I've already been through) |
Nice update, and great comment as well. I wonder if it would make sense to have something a bit more complicated which used the garbage collector to automatically reap the update thread if it's not being used, and then automatically restart it if X number of requests come in within a given time period. Pinging @kazu-yamamoto about the idea. |
Proper use of clockDateCacher in scaffolding
OK, the fix is now to use a thread to do the update. I've included a comment pointing out the alternative, since some people (eg me!) might prefer it in some situations, although it is not a big thing. |
Yes, I feel that this is bit of a hack at the moment, and something more
On 2014-01-27 08:31, Michael Snoyman wrote:
Links: |
To make code to consume less power, such automatic reaping is necessary. I noticed this issues one year ago since one guy pointed out. @snoyberg do you have any ideas to implement this? Anyway, I will consider this seriously when I will have spare time. |
I have some vague ideas, but I'd need to actually write some code to come up with something worth discussing. I'll try to get to this some time next week. |
OK, I've written up an initial stab at this. It's on FP Haskell Center: https://learning-site-staging.fpcomplete.com/user/snoyberg/auto-update I didn't end up using the garbage collector at all for this. I went with
Possible improvement: keep track of time between manual updates as well as count to determine whether or not we should spawn a thread. @kazu-yamamoto What do you think? |
Sorry for the delay. I read your code. Since it is a little bit difficult for me to understand the nested code, I made it flatten. I added comments starting with "FIXME": |
Thanks, that's certainly clearer.
Yes, it's possible with a race condition: two threads demand a value at the same time, both get a
Assertions are only checked for non-optimized builds. By putting
That's to deal with another race condition. In the race condition described above, suppose thread A is running, and is killed by thread B. Thread B then updates the IORef to refer to thread B. Then thread A's exception handler fires. We don't want to modify the IORef at all, since it refers to thread B already. Solution: only switch back to manual updates if the IORef is pointing at the current thread. |
This is unclear to me. Thread B |
What will happen in the following case?
|
I just updated the code anyway: |
Based on @snoyberg 's code, I created a simpler code. I believe this is free from race conditions thanks to https://gist.github.com/kazu-yamamoto/8951304 @snoyberg what do you think? |
The other issue is that |
You are right. How about this? |
There's still a possibility for an async exception between the call to I'm also a bit nervous about the |
I agree. I added
Since current code ensures that the internal @snoyberg what do you think? |
Imagine if an async exception was thrown between lines 43 and 44 (i.e., just when |
Things are more complicated than I expected. :-( |
This still seems a bit problematic. Consider this scenario:
|
Right. I would like to continue this discussion with a repo on github, not with a gist. Should I create a sub-directory on wai? Or another place? |
Subdirectory of |
I noticed that I don't understand your whole picture. Date cache is not a single issue. Warp also uses threads to manage timers and Fd caches. How do you stop/restart them? |
You're absolutely right, it's much bigger than just date caching. Making it a subfolder of wai does make perfect sense. |
Actually, coming to this discussion while it's happening it seems more like this should be a completely independent package. |
I have just added the auto-update sub-directory to wai: https://github.com/yesodweb/wai/tree/master/auto-update Since I'm busy in this week and the next week, and things are more complicated than I expected, I would like to resume this project in the future. |
wai-extra-2.0.3.1 fixes the most serious manifestation of failing to call the updater returned by clockDateCacher, but the same issue applies to the logger saved in the foundation in makeFoundation. This can easily be shown by adding '$(logWarn)' to the getHomeR handler in a freshly scaffolded site.
The fix here updates the cache every time the date/time getter is called, and I suppose this may not suit all situations. Ideally we might want to use the same cache as the RequestLogger, so that the update gets done for us, but that would require lots of reorganisation to expose it. Alternatively, we might write another updating thread, and start it, in makeFoundation, but that seems overly complex if the appLogger is used only rarely. Feel free to reject if you think this needs more thought!