Perrin Harkins <[EMAIL PROTECTED]> wrote: > I've never seen Apache::DBI or connect_cached return a dead handle. I > have had problems in the past with forking apps where I get back a > handle that still pings but has been shared across processes so it no > longer really works. Were you doing something with forking? Or maybe > opening handles during startup before apache forks?
Perrin, Ask Bjoern, Tim, I am opening a handle before apache forks. However, I was able to verify that Apache::DBI wasn't loaded yet at that point (no $INC{'Apache/DBI.pm'}), and I was issuing a disconnect() before the fork took place. So then I got rid of Apache::DBI entirely, deciding to rely entirely on DBI->connect_cached to do it's own pinging and reconnecting. No such luck. Inexplicably, I'd get a dead handle back, that said something like "postgres server shutting down during query" (I don't have the exact error message anymore, but it was something like that). ... so *then* I tried explicitly calling disconnect() on these handles if ping() fails. disconnect() would fail because the handle was "already disconnected", and the handle did *not* disappear out of CachedKids. Thus my solution in a previous message, which Tim so fondly called a "hack". :) It works in an extremely paranoid manner, wrapping both the ping and disconnect methods inside an eval(), and explicitly deleting the entry from CachedKids itself. Going forward: I think disconnect() should remove the handle from {CachedKids} even if the handle is already disconnected. Common sense dictates that you don't want an already disconnected handle to stick around in your cache. Maybe Apache::DBI should push a PostConfigHandler into the server that disconnects *every* DBI handle active before apache forks? Is there a valid use case for having the same DBI handle replicated across a bunch of apache child processes? When Apache::DBI refreshes it's database handle [~line 127], it doesn't look like it's disconnecting the old one. What if the old handle is in a connected, but unpingable state? Why is Apache::DBI maintaining it's own cache in the first place? Shouldn't DBI->connect_cached be able to maintain that for us? Which leads me to: Is there an easy way to enumerate *all* cached database handles in DBI? The closest i've been able to come is to enumerate the {CachedKids} of a specific driver handle, which I grab by using the (undocumented) DBI->driver() method. As far as Tim's comment about "saving the world", I never realised that would become a full time job of it's own. ;-) I'm willing to refactor Apache::DBI when I have time (maybe even tonight). After browsing through it's code, I must warn you that while I would keep the interface the same, I would change it's behaviour a fair bit (mainly the points listed above). If this is cool with everyone, I'll proceed... if not, there's I'll stick with my hack, there's plenty of other code I could be writing/fixing. :) - Tyler