FAQ
A minor issue has come up in creating low-level bindings to libpq for
safe garbage-collected languages, namely that PQfinish is the only
(AFAICT) way to close a connection but also de-allocates the memory
used to represent the database connection. It would be preferable
to call PQfinish to free the memory in a finalizer, but appilcations
need a way to disconnect from the database at a predictable and
deterministic point in time, whereas leaving a bit of memory around
until the GC finally gets to it is relatively harmless. The
low-level binding has a couple of options:

1. Ignore the issue and allow for the possibility of a segfault if
the library is used incorrectly, which is not a good situation for
"safe" languages.

2. Create a wrapper that tracks whether or not PQfinish has ever been
called, so that attempts to use a connection afterwards can be turned
into native exceptions/other forms of error signaling. This kind of
solution can introduce their own minor issues.

3. Hack libpq to export closePGconn so that libpq can safely signal
the low-level bindings of the error when a connection is used after it
is disconnected, reserving PQfinish to run in a GC-triggered
finalizer. While this is a technically preferable solution, without
getting the change into upstream sources it is also a deployment
nightmare.

Is there any particular reason why closePGconn should not be exported
from libpq?

Best,
Leon

Search Discussions

  • Tom Lane at May 14, 2011 at 3:37 pm

    Leon Smith writes:
    ... The low-level binding has a couple of options:
    1. Ignore the issue and allow for the possibility of a segfault if
    the library is used incorrectly, which is not a good situation for
    "safe" languages.
    2. Create a wrapper that tracks whether or not PQfinish has ever been
    called, so that attempts to use a connection afterwards can be turned
    into native exceptions/other forms of error signaling. This kind of
    solution can introduce their own minor issues.
    3. Hack libpq to export closePGconn so that libpq can safely signal
    the low-level bindings of the error when a connection is used after it
    is disconnected, reserving PQfinish to run in a GC-triggered
    finalizer. While this is a technically preferable solution, without
    getting the change into upstream sources it is also a deployment
    nightmare.
    Is there any particular reason why closePGconn should not be exported
    from libpq?
    Yes: it'd introduce a new externally-visible state that libpq now has to
    worry about supporting in all its operations, ie connection closed but
    not gone. This state is guaranteed to be poorly tested and hence buggy.

    I think you need a wrapper object. Given the context you're describing,
    I'd be willing to lay a side bet that you'll end up needing a wrapper
    anyway, even if it seems like you could avoid it right now. Language
    embeddings of libpq tend to accrete features...

    regards, tom lane
  • Leon Smith at May 14, 2011 at 3:59 pm

    On Sat, May 14, 2011 at 11:37 AM, Tom Lane wrote:
    Yes: it'd introduce a new externally-visible state that libpq now has to
    worry about supporting in all its operations, ie connection closed but
    not gone.  This state is guaranteed to be poorly tested and hence buggy.
    If you connect to a database over an unreliable network, you can lose
    the connection without warning at any time. Thus libpq must already
    support a "connection 'closed' but not gone" state, and I'm fine with
    making the "explicitly disconnected" state indistinguishable from the
    "connection lost" state.
    I think you need a wrapper object.  Given the context you're describing,
    I'd be willing to lay a side bet that you'll end up needing a wrapper
    anyway, even if it seems like you could avoid it right now.  Language
    embeddings of libpq tend to accrete features...
    The intention of the low-level bindings I'm working on is to keep
    features to an absolute minimum; to bind calls to C in a 1-1 fashion
    and to handle memory management and error signaling associated with
    foreign calls. Of course such a library is not intended to be
    particularly attractive for application development, but rather as a
    library that can be wrapped up into a higher-level database access
    library that's free to accrete features. :)

    Best,
    Leon
  • Markus Wanner at May 16, 2011 at 8:49 am
    Leon,
    On 05/14/2011 05:23 PM, Leon Smith wrote:
    A minor issue has come up in creating low-level bindings to libpq for
    safe garbage-collected languages, namely that PQfinish is the only
    (AFAICT) way to close a connection but also de-allocates the memory
    used to represent the database connection. It would be preferable
    to call PQfinish to free the memory in a finalizer, but appilcations
    need a way to disconnect from the database at a predictable and
    deterministic point in time, whereas leaving a bit of memory around
    until the GC finally gets to it is relatively harmless.
    It's harmless, but I think it's also useless. Or why do you want to
    keep that (libpq-private) bit of memory around beyond PQfinish()?

    I'm not sure what language or VM you have in mind, but your description
    sounds like you are writing a wrapper by definition.

    Regards

    Markus Wanner
  • Merlin Moncure at May 16, 2011 at 12:17 pm

    On Sat, May 14, 2011 at 11:23 AM, Leon Smith wrote:
    A minor issue has come up in creating low-level bindings to libpq for
    safe garbage-collected languages,  namely that PQfinish is the only
    (AFAICT) way to close a connection but also de-allocates the memory
    used to represent the database connection.    It would be preferable
    to call PQfinish to free the memory in a finalizer,  but appilcations
    need a way to disconnect from the database at a predictable and
    deterministic point in time,  whereas leaving a bit of memory around
    until the GC finally gets to it is relatively harmless.    The
    low-level binding has a couple of options:

    1.  Ignore the issue and allow for the possibility of a segfault if
    the library is used incorrectly,  which is not a good situation for
    "safe" languages.
    The 'safety' of the language has nothing to do with it. It should
    possible to maintain state outside of libpq without crashing. Which
    language by the way?
    2.  Create a wrapper that tracks whether or not PQfinish has ever been
    called,  so that attempts to use a connection afterwards can be turned
    into native exceptions/other forms of error signaling.  This kind of
    solution can introduce their own minor issues.
    This is probably your answer.
    3.  Hack libpq to export closePGconn so that libpq can safely signal
    the low-level bindings of the error when a connection is used after it
    is disconnected,  reserving PQfinish to run in a GC-triggered
    finalizer.  While this is a technically preferable solution,  without
    getting the change into upstream sources it is also a deployment
    nightmare.
    This is not going to be as helpful as you think -- in many cases the
    connection will not go 'bad' until you attempt to use...libpq runs in
    thread and does no management when you are not inside a libpq call.
    Your hypothetical callback would only get fired when you are making a
    libpq call anyways and you haven't made a case why you can't just wrap
    the query call with a a post call check to connection status.

    merlin

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppgsql-hackers @
categoriespostgresql
postedMay 14, '11 at 3:23p
activeMay 16, '11 at 12:17p
posts5
users4
websitepostgresql.org...
irc#postgresql

People

Translate

site design / logo © 2022 Grokbase