in reply to The joy of socket communication

First, let me point out that this has nothing to do with the joys of socket communications. It is sockets, in fact, that could bypass this sort of mess. This is the "joy" of linking to libraries from other projects in order to speak to them rather than using sockets. Both BSD libraries for sockets and X/Open libraries for sockets will intercommunicate over the actual sockets. You're just having problems trying to have both libraries linked into perl. If you could talk to the database servers using sockets directly rather than linking in their client libraries which use different socket libraries, then you'd only need either of the socket libraries linked into perl.

Luckily, one of (Oracle|Postgres) is itself Open Source. Would it be easier to specify that Postgres be made to accommodate the BSD sockets in Perl than to make Perl accommodate both Oracle and Postgres? How hard would it be to rebuild Postgres (or at least libpq)?

Almost anything can be solved adding another layer of indirection. Yes, I'm about to suggest a dirty hack. Actually, more than one. Those who have eaten recently may want to look away. You could have your code check which database driver is going to be used. Then, if it's Postgres, it could alter the environment variables for the libraries to preload. Then, it could exec the actual process that will connect to the database. You could do this by launching it from a shell script with the export, or by actually setting the proper values in %ENV in Perl and then exec()ing. This alone doesn't get you talking to both databases, but it does get you loading the incompatible X/Open socket library only in a branch of your process tree.

In yet another layer of indirection, you could have one process doctored to speak to Postgres as above and one left alone (since your master environment isn't bothered) to talk to Oracle. Then, you could have a third process which coordinates with both of the other two through sockets instead of through library linkages. Yes, this makes your application two processes larger than it was and more complex. You'd need to figure out a protocol for moving data back and forth across the sockets. There are such projects out in the wild as DBD::Proxy/DBD::ProxyServer and DBD::Gofer, but they seem to come with their own issues.

After all of the last two paragraphs, is it still sounding crazy to rebuild libpq linked against the BSD socket libraries?

Are the Postgres and perl in question both supplied by your OS vendor? It seems very odd that one vendor would choose the X/Open libraries in one case and BSD libraries in the other in the same system, especially for things commonly linked together like perl and Postgres client libs. Perhaps you should report an integration bug. Do the ldd outputs for libpq and for Pg.so built with an unadulterated perl vary wildly in what libraries they list?

This is, in fact, not a new failure area at all. Incompatible structure alignments and function definitions due to argument lengths from different implementations of a standard are par for the course in C development. The secret is to not need to use two incompatible versions of the same function from two similar but different libraries in the same program.

Replies are listed 'Best First'.
Re^2: The joy of socket communication
by Tux (Canon) on Dec 20, 2010 at 11:23 UTC

    I've just finished (yeah, just 20 minutes ago) a complete test in which I managed to force-build postgres in BSD type socket interface, passing both its own test suite and DBD::Pg's test suite.

    In another window, I am writing a mail to the postgres developers explaining what I did, why is is hard to do so, and some suggestions in how they could ease up the build chain to accommodate these changes.

    The basic (postgres) problem seems to lie in a fix that was explicitly added to make socket communication work on PA-RISC, which is not valid (anymore) on IA64.


    Enjoy, Have FUN! H.Merijn