lpsmith / postgresql-libpq

Low-level Haskell bindings for libpq
BSD 3-Clause "New" or "Revised" License
19 stars 18 forks source link

Wrap ForeignPtrs for Connection objects with MVars. #1

Closed jeff-davis closed 12 years ago

jeff-davis commented 12 years ago

This allows safe handling for concurrent access to connections, as well as properly handling actions after disconnect.

joeyadams commented 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.

jeff-davis commented 12 years ago

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.