mysql-simple
mysql-simple copied to clipboard
Properly use new concurrency functions in mysql
Now that mysql
finally has the proper concurrency fixes, downstream libraries need to start using the concurrency-related init functions (initLibrary
and initThread
) to get full, safe concurrency from MySQL at the C level.
The changes are here: https://github.com/paul-rouse/mysql/pull/15/files
Making a safe, easy-to-use Haskell API that includes these may prove challenging however.
It is certainly a challenge! When I fixed the Yesod scaffolding to use the new functions, I had to pass several settings to the warp
server to control, and hook into, the way the server handles threading - and I had to dive into the warp
code to check that the behaviour was really what I wanted. (Details at http://www.yesodweb.com/blog/2016/11/use-mysql-safely-in-yesod). The point is that the changes cut across the application's threading model, which may well be implemented in other libraries, and it is hard to see how mysql-simple could hide this in any useful way.
I'd love to see some proposals!
I can't recall if the C library wants you to use a connection within the same thread at all times (i.e. if it's safe to use the same connection in different threads over time). I do recall thinking over this problem years ago when I first discovered the issue in mysql
. At the time the best idea I came up with was to use some globals (it could be done with a custom monad, but that would be a drastic API change) to keep track of whether or not the library had been initialized and which capabilities (OS threads) had been initialized. Then each call to the DB from mysql-simple
would ensure that the proper initialization had been completed. This approach would obviously add some overhead which could be mitigated by introducing unsafe*
variants of many operations (i.e. offload the responsibility to the library user if speed is a problem). And/or one could introduce a custom monad [transformer] that would keep track of this state in a more optimal way.
One benefit of a monad would be that it could include safe handling of connection pooling when using transactions, which would also help make the story for concurrency better.