Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly use new concurrency functions in mysql #34

Open
3noch opened this issue Jan 13, 2017 · 3 comments
Open

Properly use new concurrency functions in mysql #34

3noch opened this issue Jan 13, 2017 · 3 comments

Comments

@3noch
Copy link

3noch commented Jan 13, 2017

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.

@3noch 3noch changed the title Properly use new concurrency primitives in mysql Properly use new concurrency functions in mysql Jan 13, 2017
@paul-rouse
Copy link
Owner

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!

@3noch
Copy link
Author

3noch commented Jan 16, 2017

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.

@lazamar
Copy link

lazamar commented Nov 27, 2024

I had segfaults in my program and managed to track it to this concurrency matter.
Using a bound thread and initLIbrary and initThread fixed it.

I wrote a wrapper to allow all database communication to be executed in a properly initialised bound thread.
For anyone interested, the code is in https://gist.github.com/lazamar/dc81d60e915e6a3a7ebbbdcaca6904da

I use it as such:

import Database.MySQL (connected, withConnection)
...
    connected connInfo $ \c -> do
      r <- withConnection c $ \conn -> query conn q params
      ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants