Skip to content

Parametrisation by the Mutex module + remove use for condition #55

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

craff
Copy link
Contributor

@craff craff commented Jun 20, 2025

I think (might be wrong) that the condition and connection state `Used was useless and that protecting all call by a mutex seems enough to me. This PR removes the condition and replace the connection state by a boolean. It also offers a functor parametrized by the mutex module.

Remark : if you can avoid the fact that I had to copy the class type connection both in .ml (without comments) and in .mli,
I would be happy. Moving all type defs in sig.ml is not so nice for the generated documentation.

Remark : In asynch mode, it could have been useful to have a Used state, but in the code before this PR send_query or send_query_prepare got the mode back to `Free. Moreover, there is no way to know when the connection is free, that is when the user does not need the connection result anymore.

@craff
Copy link
Contributor Author

craff commented Jun 20, 2025

I tested with a current ongoing project ... seems to work, but more test would be nice.

As a comment, because I protext connection use my own implementation or connectionPool, but
because bug are always possible, I use this kind of code:

module Check = struct
  type t = bool Atomic.t
  let create () = Atomic.make false
  let lock m =
    if not (Atomic.compare_and_set m false true) then
      failwith "Concurrent use of a Postgres connection (at lock)"
  let unlock m =
    if not (Atomic.compare_and_set m true false) then
      failwith "Concurrent use of a Postgres connection (at unlock)"
end

module Postgresql = struct
  include Postgresql

  include Connection(Check)
end

I added this in the documentation.

@mmottl
Copy link
Owner

mmottl commented Jun 22, 2025

Unfortunately, people may still need cancellation of synchronous queries. Keeping the mutex locked during the operation would prevent cancellation. That's why I don't think we should be merging this, it would probably break some people's code.

I'm not sure what a good solution would look like, but it might be a good idea to use the more secure, modern API: https://www.postgresql.org/docs/current/libpq-cancel.html

I believe we may need to protect the cancel object with a separate mutex so only one cancellation can happen at a time. I believe it may be safe to otherwise access the connection and the cancel object simultaneously. These changes would be a bit more involved, and I unfortunately don't have time to help with this right now.

@craff
Copy link
Contributor Author

craff commented Jun 23, 2025 via email

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

Successfully merging this pull request may close these issues.

2 participants