Closed jeff-davis closed 12 years ago
This library used to use MVar
for the Connection
object, but that was changed in commit eed4747c. See the commit message for the rationale.
The postgresql-simple
library does use an MVar lock. If postgresql-libpq
did, too, that would be two levels of MVar
locking—unnecessary overhead.
Another problem with wrapping the Connection
object in an MVar
is that the safety it provides does not compose. For example, if you execute a query with exec
, then call errorMessage
when it fails, it's possible that a second thread may execute a query in between and change the error message.
The "safety" problem you mention is not a safety problem, any more than one thread sending an INSERT interleaved into another thread's multi-statement transaction. In other words, the mere idea of using threads and a database driver means the application programmer needs some awareness of concurrency, interleaving, etc. Moreover, the application programmer wants those things, otherwise they wouldn't be sharing a connection between threads; they'd just give each thread its own connection.
The safety problems I am trying to fix are crashes, memory corruption, etc. This is a philosophical thing for me -- the first level of driver above the C code should offer safety from these kinds of problems. That allows a second-level driver, like postgresql-simple, to be more ambitious and clever without tripping over subtle errors that shouldn't happen in haskell.
I'm not entirely convinced by the overhead problem, either. If it's handled by postgresql-libpq, does postgresql-simple really need to do it too? Does it matter in real-world applications more than some of the other safety measures that haskell offers?
If you have a different philosophy, that's OK, please simply reject the pull request on those grounds. I won't be offended.
This allows safe handling for concurrent access to connections, as well as properly handling actions after disconnect.