-
Notifications
You must be signed in to change notification settings - Fork 59
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
Event-driven reaper #21
Conversation
An event-driven reaper sounds like a good idea. I haven't looked closely at the implementation of setAlarmVar :: MVar UTCTime -> UTCTime -> IO ()
setAlarmVar mv wakeUpTime = tryTakeMVar mv >>= \case
Nothing -> putMVar mv wakeUpTime
Just wakeUpTime' -> putMVar mv (min wakeUpTime wakeUpTime') What happens when another thread executes and completes |
The reaper thread itself is also repeatedly calling That jazz was to avoid a rare deadlock that took weeks to track down, but which I now think cannot occur for other reasons, so I will try and simplify it. |
Ok, I've made that simplification to |
A starter for ten is at DaveCTurner@d434623 Comments welcomed. Issues I'm aware of are:
I'm concerned that I don't fully understand the performance constraints so may have done something awful in terms of performance. |
Now a PR. Have been having trouble with high quiescent CPU usage in a low-usage-but-large-heap service caused by the idle GC which we've traced back to using Switching off the idle GC cuts the quiescent CPU usage from 30% down to 0.3% which makes the difference between having to use multiple t2.large instances and a single t2.micro. This PR gives a similar improvement by only running the reaper when there's something to reap. |
I think I should be maintaining pool but unfortunately I don't have much time to spend on it these days. Maybe @bos can be convinced to also make @DaveCTurner a maintainer. I did review the PR and except for the following it looks good to me: In the newAlarmClock' :: TimeScale t => (AlarmClock t -> t -> IO ()) -> IO (AlarmClock t)
newAlarmClock' onWakeUp = do
joinVar <- newEmptyMVar
ac <- atomically $ AlarmClock (readMVar joinVar) <$> newTVar AlarmNotSet <*> newTVar False
void $ mask $ \restore -> forkIO $ restore (runAlarmClock ac (onWakeUp ac))
`finally` putMVar joinVar ()
return ac An even better alternative is to use either the async or threads package. |
Good point, I'll fix that. |
51ac25e
to
6e80f28
Compare
Ok, fixed in Also, apropos of #27, this version of |
@DaveCTurner thanks! Could you please bundle the commits in this PR as a single one? That makes the history a bit easier to read. |
6e80f28
to
c065d09
Compare
c065d09
to
9a994b8
Compare
Sure, there you go. |
Tidying up by closing some of my stale PRs. Sorry for the noise. |
Hi,
I'd like to use the resource-pool package, but the polling model for the reaper doesn't work well with what I'm trying to do. Running the reaper every second is too frequent, but simply decreasing the polling frequency means that stale resources will hang around for too long.
I've made an event-driven reaper in the past as part of another project and it worked well before, and I've now extracted this basic functionality into the alarmclock package.
Would you consider a change to resource-pool to make it use this event-driven model rather than the current polling one? I will prepare a pull request if so.
I'm willing to believe that
alarmclock
is not suitable in its current form, or has some subtle bug or performance issue, so if you have comments for how it could be improved then I'd be glad to hear them.Cheers,