
Marcin 'Qrczak' Kowalczyk writes:
It does not necessarily make bracket unavailable. Just put it somewhere outside, when it's known when the file will need to be closed.
The problem is that there is a gap of coverage, so to speak. It works like this in my code: input -> iodriver --> connection handler --+ | /|\ | output <--+ +-----------------------------+ (Event, State) The I/O driver is a StateT monad which calls the (various) connection handlers every time new input is available from the network. The handlers are StateT monads, too, and their respective state is stored in the I/O driver's state when they return. Now I have the case where a connection handler needs open a handle -- and keep it open for the life-time of the connection. But what happens if I receive an exception after the handle has been opened but before the connection handler has returned? The handle is _supposed_ to leave the connection handler, so it cannot attach any 'finally' clauses or 'bracket' calls. And doing it in I/O driver is too late. Neither will catching the exception in the I/O driver help, because the intermediate state, which contained the open handle, is lost. The only solution I would know is to put the entire state of the connection handler into an MVar, so that any changes to it are immediate for the I/O driver. But that approach feels like overkill to me. I can't judge what it would to the performance of the whole application either. Doing every little state access through an MVar can't be fast, can it? If there is another solution, then I'd be delighted to hear about it. Peter