Cap memory usage for one thread without disrupting other threads
I would like to be able to programmatically guard against runaway memory usage by a thread. If it occurs, I want to be able to handle it gracefully, and I do not want other threads to be disrupted.
Note: I asked this on StackOverflow a few days ago. The paragraph below is copied from the question.
For example, suppose I want to write a server, hosting a scripting language interpreter, that users can connect to. It's Turing-complete, so programs could theoretically use unlimited memory or time. Suppose each client is handled with a separate thread. If a client writes an infinite loop that consumes memory very quickly, I want to ensure that the thread consumes no more than, say, 1 MB of memory, before being alerted with an exception. I do not want other users to be affected when that happens.
Ideally, it would be a function like this:
catchHeapOverflow :: Int64 -> IO a -> IO a -> IO a catchHeapOverflow limitBytes handler action = ...
It sets a memory usage limit for the current thread (and any child threads, ideally). If this limit is surpassed while performing the action, it invokes the handler (with the usage limit lifted).
Granted, the notion of a thread using too much memory makes less sense when objects are shared between threads. Should a thread be blamed for pointing to a lot of memory that another thread gave it? I don't know. Should a thread be blamed for consuming a lot of memory while evaluating a thunk? Absolutely. In my opinion, handling the edge cases perfectly is not as important as being able to do this at all. As long as the user performs all the necessary calculations in one thread and does not export unforced thunks to other threads, s/he should be fine.