-
Notifications
You must be signed in to change notification settings - Fork 297
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
Make thread-safe wrapper around getStmtConn
.
#982
base: master
Are you sure you want to change the base?
Conversation
, stmtQuery = \x -> do | ||
liftIO $ do | ||
active <- readIORef iactive | ||
when (not active) . throwIO $ StatementAlreadyFinalized sql |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is basically useless, we can instead rely on the MVar to track if the query is alive and "refresh" it if someone tries to use it again, but this complicates the Acquire
logic and I'm too tired to fix it right now.
Running concurrent queries is threadsafe and works with this PR, but concurrent inserts result in utter garbage due to the two stage ROWID based method of returning the key that was just inserted (for SQLite and presumably the same of MySQL). |
Thanks for all the work on this stuff. I'll try to get to it soon! |
This change in behavior is complicated enough that I'd want to gate it behind a major version bump, which means I also want to collect other breaking changes into a big release. I could be convinced to release it as a patch version, but only with sufficient testing or correctness guarantees. I'd hate to release a version and have someone's application deadlock unexpectedly. However, if there application would have otherwise blown up or done something bad, then I might be okay with it too. |
Yeah, this PR was/is more of a proof-of-concept/starting point |
@merijn Now that it's the new year, how are you feeling about this? I've reviewed it a few times and I feel good about the change. |
I think this one is still a bit dicy, since as I commented before concurrent inserts basically corrupt the "safe" keys you get back. I think it can be made to work, but it might require overhauling the way inserts are done in all the SQL backend, so that's quite some work. |
@merijn Do you think you'll have time to do this in the next week or two? I'm happy to accept an improvement to the status quo, even if it doesn't completely solve the problem, provided that the remaining issues can be documented. |
I am opposed to merging this PR. This is a breaking change for all persistent users to implement a backend-specific feature. Please implement this as part of the SQLite backend, not as part of persistent. |
This PR (as is) can't be merged, since it doesn't actually work on any backend and I don't have time to get things working anytime soon. That said, this is also wrong:
I haven't tested to confirm, but I can't see a way the current implementation isn't broken for all persistent backends. Now, admittedly the other backends rely on connection pools more, so are less likely to run into breakage as they don't run into issues with concurrent queries from separate threads. However, that's not all that's broken, running multiple queries in a conduit from the same thread is also horribly broken, and half the |
You are referring to the EDIT: Moving discussion back to the issue. |
My team is affected by this and it results in the postgres error:
From code like: withDB1
. Conduit.runConduit
$ (Persist.selectSource [] [] .| Conduit.mapM_
(\stuff ->
runMyMonadT env . withDB2 . void $ Persist.upsert myModel)
) |
Refer to #981.