Re: Apache::DBI and DBIx::*
On Fri, 2004-08-13 at 15:25, John Siracusa wrote: > What does a DBIx::* module have to do in order to correctly call > Apache::DBI's no-op version of disconnect() when running under mod_perl with > Apache::DBI? It needs to not set RootClass. Apache::DBI essentially subclasses DBI, which is what RootClass does as well. > Run it under httpd -X to further isolate the problem and you'll see that the > first request works, but all subsequent requests fail. This happens because > the disconnect() call actually calls the "real" disconnect method instead of > the Apache::DBI implementation, which is a no-op. Why call disconnect at all? Are you trying to run this as normal CGI too? - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
while perrin addressed your other issues, I thought I'd bring this up as a learning point :) > > return 200; this is wrong - you should be returning OK (0) not HTTP_OK (200) from handlers if everything is swell. while 200 works in mp1 (due to mod_perl "guessing" what you meant) you cannot do this in mod_perl 2.0. so, if you do it correctly now you'll have one less thing to migrate later :) --Geoff -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 15:32:03 -0400, Perrin Harkins <[EMAIL PROTECTED]> wrote: > On Fri, 2004-08-13 at 15:25, John Siracusa wrote: > > What does a DBIx::* module have to do in order to correctly call > > Apache::DBI's no-op version of disconnect() when running under mod_perl with > > Apache::DBI? > > It needs to not set RootClass. Apache::DBI essentially subclasses DBI, > which is what RootClass does as well. Er, yeah, "essentially" :) All the crazy re-blessing that goes on is quite a mess, IMO. So what you're saying is that DBIx::* and Apache::DBI will simply never get along because they both want to do the same thing, but use different (and apparently incompatible) methods to do so? > > Run it under httpd -X to further isolate the problem and you'll see that the > > first request works, but all subsequent requests fail. This happens because > > the disconnect() call actually calls the "real" disconnect method instead of > > the Apache::DBI implementation, which is a no-op. > > Why call disconnect at all? Are you trying to run this as normal CGI > too? The first answer is that I'm calling disconnect because it's The Right Thing To Do. Maybe some people think just letting things go out of scope is more "(mod_)perl-ish", but I always wonder if those people don't call close(FILE) either ;) Anyway, I'm not one of those people. The second answer is that it's common (and usually desirable) for certain DBI-using modules to be used both in both web and offline contexts. (The example was heavily simplified, obviously.) -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 15:38:41 -0400, Geoffrey Young wrote: > > return 200; > > this is wrong - you should be returning OK (0) not HTTP_OK (200) from > handlers if everything is swell. while 200 works in mp1 (due to mod_perl > "guessing" what you meant) you cannot do this in mod_perl 2.0. so, if you > do it correctly now you'll have one less thing to migrate later :) Whoops, I was just trying to reduce the length of the example code by not use()ing Apache::Constants :) -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
Perrin Harkins wrote: On Fri, 2004-08-13 at 15:25, John Siracusa wrote: What does a DBIx::* module have to do in order to correctly call Apache::DBI's no-op version of disconnect() when running under mod_perl with Apache::DBI? It needs to not set RootClass. Apache::DBI essentially subclasses DBI, which is what RootClass does as well. Also make sure that you read: http://perl.apache.org/docs/1.0/guide/databases.html#Opening_Connections_With_Different_Parameters -- __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
John Siracusa wrote: On Fri, 13 Aug 2004 15:38:41 -0400, Geoffrey Young wrote: return 200; this is wrong - you should be returning OK (0) not HTTP_OK (200) from handlers if everything is swell. while 200 works in mp1 (due to mod_perl "guessing" what you meant) you cannot do this in mod_perl 2.0. so, if you do it correctly now you'll have one less thing to migrate later :) Whoops, I was just trying to reduce the length of the example code by not use()ing Apache::Constants :) Apache::Constants::OK == 0, not 200 -- __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 12:51:32 -0700, Stas Bekman <[EMAIL PROTECTED]> wrote: > John Siracusa wrote: > > On Fri, 13 Aug 2004 15:38:41 -0400, Geoffrey Young wrote: > > > >>> return 200; > >> > >>this is wrong - you should be returning OK (0) not HTTP_OK (200) from > >>handlers if everything is swell. while 200 works in mp1 (due to mod_perl > >>"guessing" what you meant) you cannot do this in mod_perl 2.0. so, if you > >>do it correctly now you'll have one less thing to migrate later :) > > > > Whoops, I was just trying to reduce the length of the example code by not > > use()ing Apache::Constants :) > > Apache::Constants::OK == 0, not 200 Thus the "whoops" :) I was just saying that I got it wrong because I always use Apache::Constants in actual code. -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 12:50:44 -0700, Stas Bekman <[EMAIL PROTECTED]> wrote: > Also make sure that you read: > http://perl.apache.org/docs/1.0/guide/databases.html#Opening_Connections_With_Di fferent_Parameters Unfortunately, setting RootClass after the connect doesn't have the desired effect (and isn't even valid, as far as I can tell; local()izing it throws an exception) So, what is the final answer here? Is this not a bug at all? If not, what do people do when they need to create code that uses DBIx:: modules and runs in both Apache::DBI and offline contexts? Call $dbh->disconnect() unless $ENV{'MOD_PERL'}? Ick... -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
> Er, yeah, "essentially" :) All the crazy re-blessing that goes on is quite > a mess, IMO. Agreed. I would like to replace Apache::DBI with something oriented towards connection management rather than porting old CGI scripts. I don't like the disabling of disconnect. The old Apache::DBI could stick around just for that purpose. > So what you're saying is that DBIx::* and Apache::DBI will simply > never get > along because they both want to do the same thing, but use different > (and > apparently incompatible) methods to do so? They both subclass, and multiple inheritance might not work here, but you can try it. Put this code somewhere after you load Apache::DBI: psuh @Apache::DBI::st::ISA, 'DBIx::ContextualFetch'; Note that this has nothing to do with DBIx::* as a whole. This one particular module that you are using happens to subclass DBI. Most of them don't. > The first answer is that I'm calling disconnect because it's The Right > Thing To Do. I can't see how. You know it's a no-op. You don't actually want it to disconnect. Why call it? The whole disabling-disconnect thing exists only for the purpose of porting old CGI scripts. > Maybe some people think just letting things go out of scope is more > "(mod_)perl-ish", but I always wonder if those people don't call > close(FILE) either ;) Now that Perl has lexically scoped filehandles, there isn't any reason to explicitly call close() in most cases. ;) > The second answer is that it's common (and usually desirable) for > certain DBI-using modules to be used both in both web and offline > contexts. I share a lot of code that way too, but I typically keep the connection open until the end of the command-line script and then close it there. - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
Perrin Harkins wrote: Er, yeah, "essentially" :) All the crazy re-blessing that goes on is quite a mess, IMO. Agreed. I would like to replace Apache::DBI with something oriented towards connection management rather than porting old CGI scripts. I don't like the disabling of disconnect. The old Apache::DBI could stick around just for that purpose. IMHO, that should be folded into DBI::Pool, whose prototype was written about 2 years ago. I wasn't able to work on it since then. It's possible that Tim Bunce will work on it, or may be someone else, or me once mp2 is released. -- __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 16:22:00 -0400, Perrin Harkins <[EMAIL PROTECTED]> wrote: >> So what you're saying is that DBIx::* and Apache::DBI will simply never get >> along because they both want to do the same thing, but use different (and >> apparently incompatible) methods to do so? > > They both subclass, and multiple inheritance might not work here, but > you can try it. Put this code somewhere after you load Apache::DBI: > > psuh @Apache::DBI::st::ISA, 'DBIx::ContextualFetch'; Well, I'm actually using a class that is a subclass of that DBIx:: class, so I just added the disconnect() method (posted earlier) to the subclass. It just seemed odd to me to be doing stuff in service of Apache::DBI, which was totally transparent until then. > Note that this has nothing to do with DBIx::* as a whole. This one > particular module that you are using happens to subclass DBI. Most of > them don't. Ah, so I just got lucky, eh? :) > Now that Perl has lexically scoped filehandles, there isn't any reason > to explicitly call close() in most cases. ;) Tsk, for shame. Just wait until you forget to call close() after writing to a file... ;) > > The second answer is that it's common (and usually desirable) for > > certain DBI-using modules to be used both in both web and offline > > contexts. > > I share a lot of code that way too, but I typically keep the connection > open until the end of the command-line script and then close it there. That assumes the connection was opened by (or is at least accessible from) the script itself. If the connection is opened and managed by a module (which may abstract things such that you aren't even supposed to know whether or not it has to hit a database at all) rather than by your script, that's not an option. I tend to like abstractions like that, and I certainly want "model"-type objects to be able to exist happily in both mod_perl and offline contexts. I also wrap DBI rather than subclass it when I have a choice. Subclassing DBI in general is way too hard, IMO, and it wasn't my choice to use this DBIx:: module, but such is life. I'm mostly just trying to determine if/where to send a bug report. The answer seems to be no/nowhere. -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 2004-08-13 at 16:37, Stas Bekman wrote: > IMHO, that should be folded into DBI::Pool I'm not really interested in tackling pooling, since I don't plan to run threads. All that I really want my module to do is extend the DBI->connect_cached() method by adding the cleanup handler stuff from Apache::DBI. - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 13:37:55 -0700, Stas Bekman wrote: > Perrin Harkins wrote: > > I would like to replace Apache::DBI with something oriented > > towards connection management rather than porting old CGI scripts. I > > don't like the disabling of disconnect. The old Apache::DBI could stick > > around just for that purpose. > > IMHO, that should be folded into DBI::Pool, whose prototype was written > about 2 years ago. I wasn't able to work on it since then. It's possible > that Tim Bunce will work on it, or may be someone else, or me once mp2 is > released. I like the fact that both connect() and disconnect() are overridden. Of course, a proper server-wide DBI connection pool would be nice, but I wouldn't want to give up the ability to have the same code "magically" get its connection from the pool by calling connect() and return it to the pool by calling disconnect() when running in a certain context. Yeah, Yet Another DBI Wrapper could do that for me too, but I don't think the semantics described above are too crazy. Maybe just modify DBI and add "smart" methods named retain() and release() that call connect() and disconnect() when offline, but do the right thing when connection pooling is in effect? Hrm, something tells me Tim wouldn't go for that :) Anyway, especially in a future server-wide connection pooling context, some sort of method of returning connections to the pool prior to the end of the request cycle is very useful. Why hog it if you don't need it? Calling disconnect() is as good a signal as any the the connection is up for grabs again. -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 2004-08-13 at 16:43, John Siracusa wrote: > It > just seemed odd to me to be doing stuff in service of Apache::DBI, which was > totally transparent until then. That's one of the things I don't like about Apache::DBI. I don't want it to be magical. > > Now that Perl has lexically scoped filehandles, there isn't any reason > > to explicitly call close() in most cases. ;) > > Tsk, for shame. Just wait until you forget to call close() after writing to > a file... ;) That's the point actually -- perl closes it for me when it goes out of scope. > That assumes the connection was opened by (or is at least accessible from) > the script itself. If the connection is opened and managed by a module > (which may abstract things such that you aren't even supposed to know > whether or not it has to hit a database at all) rather than by your script, > that's not an option. True, you have to structure your code for this. Making all calls to open a db connection go through one utility class is my approach, but may not work for everyone. Hmm, I wonder why my Class::DBI unit test scripts never get the disconnect warning? I should look into that. Class::DBI uses connect_cached. > I also wrap DBI rather than subclass it when I have a choice. Me too. Subclassing DBI (or Apache or Apache::Request for that matter) is nearly always a bad idea IMO. In this one case it makes some sense though, since that module is literally all about changing the behavior of DBI methods. - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 16:45:59 -0400, Perrin Harkins <[EMAIL PROTECTED]> wrote: > On Fri, 2004-08-13 at 16:37, Stas Bekman wrote: > > IMHO, that should be folded into DBI::Pool > > I'm not really interested in tackling pooling, since I don't plan to run > threads. All that I really want my module to do is extend the > DBI->connect_cached() method by adding the cleanup handler stuff from > Apache::DBI. Even without threads, wouldn't you rather have each apache child pulling connections from a shared, server-wide pool rather than holding onto at least one connection a piece whether they need it or not? With the Apache::DBI system on a typical db-backed web site, the max number of simultaneous (mod_perl) requests is pretty much limited by the max number of simultaneous open database connections (since, long term, every apache child will be hanging onto at least one db connection). A server-wide pool removes that limitation, allowing each request to retain, use, and then release any number of connections (possibly zero) within the course of a single request. Maybe that'd lead to too much contention, I don't know, but I assumed something like that was a long-term mod_perl2/apache2/perl6 goal. Or maybe it's just a personal fantasy... :) -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 17:02:27 -0400, Perrin Harkins <[EMAIL PROTECTED]> wrote: > > > Now that Perl has lexically scoped filehandles, there isn't any reason > > > to explicitly call close() in most cases. ;) > > > > Tsk, for shame. Just wait until you forget to call close() after writing to > > a file... ;) > > That's the point actually -- perl closes it for me when it goes out of > scope. Ah, but perl doesn't check the return value! :) Something tells me you haven't been bitten by this bug yet, but let me save you the grief. When, say, your disk fills up and you let that file handle go out of scope, close() will silently fail when trying to flush the buffers to disk. The moral of the story: always call close() explicitly *and check the return value* when writing to a file. -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 2004-08-13 at 17:05, John Siracusa wrote: > Even without threads, wouldn't you rather have each apache child pulling > connections from a shared, server-wide pool rather than holding onto at > least one connection a piece whether they need it or not? Sure. Can you figure out a way to do it? It is possible on unix systems to pass filehandles between processes, but that kind of C programming is not something I'm likely to tackle myself. > With the Apache::DBI system on a typical db-backed web site, the max number > of simultaneous (mod_perl) requests is pretty much limited by the max number > of simultaneous open database connections (since, long term, every apache > child will be hanging onto at least one db connection). You actually have a site where you can run more apache children than database connections? I have never seen such a beast. IMO the only real advantage of having pooling over the way things are now (assuming you run a front-end proxy for static stuff) is that sites which use different database logins for each user will be able to use persistent connections. Right now, that would result in a very large number of connections. > Maybe that'd lead to too much contention, I don't know, but I assumed > something like that was a long-term mod_perl2/apache2/perl6 goal. Or maybe > it's just a personal fantasy... :) Perl6 would presumably mean mod_perl 3. Anyway, the pooling thing is mostly driven by how much Java people hype it. The usefulness of pooling is pretty limited for a site that actually uses database connections on every request. - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On Fri, 2004-08-13 at 17:15, John Siracusa wrote: > Something tells me you haven't been bitten by this bug yet, but let me save > you the grief. When, say, your disk fills up and you let that file handle > go out of scope, close() will silently fail when trying to flush the buffers > to disk. If you're concerned about that, you should actually check the return value of print() as well. - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
Perrin Harkins wrote: On Fri, 2004-08-13 at 16:37, Stas Bekman wrote: IMHO, that should be folded into DBI::Pool I'm not really interested in tackling pooling, since I don't plan to run threads. Support for threads is only partial functionality of DBI::Pool. Otherwise it should be a ground-up rewrite based on the experiences with Apache::DBI and other wrappers so far. Apache::DBI should become just a thin wrapper on top of DBI::Pool, to handle things like connect_on_init. All that I really want my module to do is extend the DBI->connect_cached() method by adding the cleanup handler stuff from Apache::DBI. Sure, just thought that you are planning to work on yet another Apache::DBI version, so I've suggested to direct the effort into something new that (will) solves it all. -- __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
Stas Bekman wrote: Support for threads is only partial functionality of DBI::Pool. Otherwise it should be a ground-up rewrite based on the experiences with Apache::DBI and other wrappers so far. Apache::DBI should become just a thin wrapper on top of DBI::Pool, to handle things like connect_on_init. The thin wrapper is actually the only part I'm talking about building here. Persistent connections are already available in standard DBI, so I don't need to do anything for that. My goal is just to make something that adds the mod_perl-specific stuff like connect_on_init and a cleanup handler, but doesn't do any of the annoying magical stuff, like automatically making connections persistent (just call connect_cached() for that) or disabling disconnect. The magic stuff could stick around in Apache::DBI for backwards compatibility and for people who want to port CGI scripts with it. I don't have any time to work on this right now, so it's sort of a moot point. When I do get time for it, I'll post here and we can discuss the design in more detail. - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
On 8/13/04 5:22 PM, Perrin Harkins wrote: > On Fri, 2004-08-13 at 17:05, John Siracusa wrote: >> Even without threads, wouldn't you rather have each apache child pulling >> connections from a shared, server-wide pool rather than holding onto at >> least one connection a piece whether they need it or not? > > Sure. Can you figure out a way to do it? Probably not in Perl 5 and apache 1.x, but I hope Perl 6, apache 2, and mod_(perl6|parrot) will be flexible enough... > You actually have a site where you can run more apache children than > database connections? I have never seen such a beast. Maybe your database is just too beefy? :) I've worked on sites that would routinely bump into a database connection limit of ~200 during traffic spikes. (And yes, of course static content was served elsewhere :) >> Maybe that'd lead to too much contention, I don't know, but I assumed >> something like that was a long-term mod_perl2/apache2/perl6 goal. Or maybe >> it's just a personal fantasy... :) > > Perl6 would presumably mean mod_perl 3. ...or mod_parrot or something, especially if this Parrot DBI-like-core thing takes off (I forget the name they're using) > Anyway, the pooling thing is mostly driven by how much Java people hype it. > The usefulness of pooling is pretty limited for a site that actually uses > database connections on every request. I've worked on sites that use a "session" (MySQL) database connection on every request, but don't use a "main" (Postgres) database connection nearly that often. If that main database is shared by several sites/apps, it can become the bottleneck. Maybe read-only replication would help, but it still seems wasteful. -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::*
John Siracusa wrote: Even without threads, wouldn't you rather have each apache child pulling connections from a shared, server-wide pool rather than holding onto at least one connection a piece whether they need it or not? Sure. Can you figure out a way to do it? Probably not in Perl 5 and apache 1.x, but I hope Perl 6, apache 2, and mod_(perl6|parrot) will be flexible enough... It's not a matter of flexibility, but rather one of difficult coding and potential issues with closed source database client libraries. The coding would be in C, and it would involve passing data structures and open sockets between running processes. It's way beyond my level of unix-foo, but if someone out there wants to try it, there is nothing needed for it that hasn't already been there for years. Making DBI::Pool work for threads is probably easier, and that could also be done today if someone has both the incentive and the C-coding skills to deal with the threading and XS issues. I've worked on sites that use a "session" (MySQL) database connection on every request, but don't use a "main" (Postgres) database connection nearly that often. In that situation, if a significant percentage of requests need sessions but not the main database, and the difference is determined by URL, I would move the session-only requests to a separate server. Pooling sounds nice, but is a non-trivial problem, and only helps in a few specific situations. In the common case, where every request to the app-server needs a database handle, it is not very useful. - Perrin -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: Apache::DBI and DBIx::Class
First off, please let me apologize for the tone of my last email, It was certainly not what I intended. I have to stop having discussions about system design and philosophy after having meetings with a developer who's most intelligent statement was "It works on my machine". Cold Fusion not mod-perl, and the problem is not with Cold Fusion. >> IMHO, worth exactly what you paid for it This was meant to refer to my opinion, not your code, sorry. On 27/06/11 09:38 PM, David E. Wheeler wrote: Yeah, too magical. I removed support for it in Bricolage years ago, though I can't remember the details of why anymore. connect_cached() worked much better for me (though it's kind of a PITA to set up). Never ran Bricolage in production. Did run a test system, ugh. I suspect the issue was with the Bricolage code, not Apache::DBI. I have never used connect_cached, never had the need. snip. I don't understand. PostgreSQL supports cursors, and you can read from them using FETCH. http://www.postgresql.org/docs/current/static/sql-fetch.html Might be my lack of knowledge of Oracle at work here, though. Postgres supports it but DBD::Pg doesn't, not with the standard DBI fetch* APIs. At least as of last year it didn't. If I didn't have to spend all my time reviewing and running other peoples code I would take the time to add the functionality. Well, DBIx::Connector does not do connection pooling (or caching), so that wouldn't be a problem. I am being unclear here. Each apache child/process will open 2 connections, one for Apache::DBI and one for DBIx::Class or DBIx::Connector. Possibly more connections if a variety of different modules are being used, each with it's own connection handling. This explains an issue I saw with a client 2 months ago where the number of open database sessions doubled with the introduction of some new code based on DBIx::Class. I believed the doubling of sessions was a symptom of poor code. Neither I nor their developers had any idea that Apache::DBI was being bypassed. Luckily it was a prototype and the issue was caught while stress testing in their staging environment. And so into the design and philosophy. As an admin I need to be able to deploy code without side effects that may adversely affect other processes or the system itself. Now at least you document your connection logic, so that if I do a quick review I can see the implications (I doubt I would actually catch it but at least you are giving me a chance :) whereas for DBIx::Class, if there is documentation about connecting I don't know where it is. Even so, I believe the logic should be if Apache::DBI use it else use my stuff I do not know the internals of DBI or the derived classes so I do not know if the above is practical. However, it is respectful of the environment it is going to run in. Writing code that specifically ignores how a system is configured is ... impolite! And yet Apache::DBI also has side effects. I revoke ALTER SESSION from any schema/user that will be accessed via Apache::DBI as there will be some unaware developer who will change the session characteristics (to get a different data format perhaps) and then will not change it back. And so the next time the connection/handle is used the code fails. Is this his fault? I don't believe so. It is a systems issue not a development issue. Yeah it was a lot of fun debugging the issue that resulted in that solution :) What I find so frustrating is that with all these magnificent tools we have now, modern hardware, screaming fast network, Apache, perl, mod_perl, the networking libraries and such I am still dealing with the same problems I had to deal with 10 and 15 years ago: - let the database do the work - do not try to configure network parameters - close all connections (file handles, RPC, serial port, network and database) - do not assume your code completes properly. - do not try to manage or allocate hardware resources, just use them - you have to share, your code is not the only thing running - the problem is not with the tools you are using, it is your code And it must be extremely frustrating to be a developer, have his systems people chew him out for some problem, when he/she has not changed anything and the problem is caused by an "impolite" library. And the database side is usually pretty good, the modules used for SCADA are much worse. It is inherent in the nature of perl, you have this wonderful library called CPAN, but, how do you ensure that the modules you use do what you want and nothing more? Do you really want to review (and understand) DateTime.pm? And finally back to the Cold Fusion issue : "You don't get paid to make it run on your machine, you get paid to make it run on mine!" I love my job, I love my job, I love my job ;) Sorry once again, Dave Best, David -- Dave Morgan Operations Manager, BorealE
Re: Apache::DBI and DBIx::Class
> "Dave" == Dave Morgan writes: >> >> You lost me. But really, I strongly recommend against the use of >> Apache::DBI. Some discussion here: >> >> http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description >> Dave> And having read that, I strongly recommend against the use of DBIx-Connector. Dave> But then I'm just a production DBA :) Really? I've been moving my clients *towards* it. It solves a lot of useful problems. I did a mashup of DBIx::Connector with SQL::Interpolate and ended up with a very nice base class for handwritten SQL (no ORM) for a recent project. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.posterous.com/ for Smalltalk discussion
Re: Apache::DBI and DBIx::Class
Hi Randal, >>> >>> You lost me. But really, I strongly recommend against the use of Apache::DBI. Some discussion here: >>> >>> http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description >>> > >Dave> And having read that, I strongly recommend against the use of DBIx-Connector. >Dave> But then I'm just a production DBA :) > >Really? I've been moving my clients *towards* it. It solves a lot of >useful problems. > >I did a mashup of DBIx::Connector with SQL::Interpolate and ended up >with a very nice base class for handwritten SQL (no ORM) for a recent >project. Would you care to share that 'mashup' it sounds interesting Greg *** Please consider the environment before printing this e-mail. This message is intended solely for the individual(s) and entity(s) addressed. It is confidential and may contain legally privileged information. The use, copying or distribution of this message or any information it contains, by anyone other than the addressee, is prohibited. If you have received this message in error, please notify postmas...@orica.com. The mailbox address from which this message has been sent is for business mail only. Mail sent to it may be subject to security scanning and delivery on non-business messages sent to this address may not occur. Thank you. ***
Re: Apache::DBI and DBIx::Class
On Jun 28, 2011, at 11:34 AM, Dave Morgan wrote: > First off, please let me apologize for the tone of my last email, > It was certainly not what I intended. No worries. I assumed it was a caffeine shortage. That's what I suffer from sometimes. :-) > I have to stop having discussions about system design and > philosophy after having meetings with a developer who's most > intelligent statement was "It works on my machine". Cold Fusion not > mod-perl, and the problem is not with Cold Fusion. Someone put cold fusion in your espresso. That can cause a bad day no question. > >> IMHO, worth exactly what you paid for it > This was meant to refer to my opinion, not your code, sorry. Ah, okay. > Never ran Bricolage in production. Did run a test system, ugh. > I suspect the issue was with the Bricolage code, not Apache::DBI. Based on what evidence, exactly? > I have never used connect_cached, never had the need. If you rely on Apache::DBI, you wouldn't need connect_cached, of course. > Postgres supports it but DBD::Pg doesn't, not with the standard DBI > fetch* APIs. At least as of last year it didn't. If I didn't have to spend > all my time reviewing and running other peoples code I would take the time > to add the functionality. What's wrong with SQL? Example: #!/usr/local/bin/perl -w use v5.14; use utf8; use DBI; my $dbh = DBI->connect( 'dbi:Pg:dbname=try', '', '', { PrintError=> 0, RaiseError=> 1, AutoCommit=> 1, pg_enable_utf8=> 1, pg_server_prepare => 0, } ); $dbh->begin_work; $dbh->do('CREATE TABLE foo (id INT)'); $dbh->do('INSERT INTO foo VALUES (1), (2), (3), (4), (5), (6)'); $dbh->do('DECLARE getfoo CURSOR FOR SELECT id FROM foo'); my $sth = $dbh->prepare('FETCH FORWARD 2 FROM getfoo'); for (1..3) { say $_; $sth->execute; while (my $r = $sth->fetch) { say ".. $r->[0]"; } } $dbh->rollback; Output: 1 .. 1 .. 2 2 .. 3 .. 4 3 .. 5 .. 6 >> Well, DBIx::Connector does not do connection pooling (or caching), so that >> wouldn't be a problem. > > I am being unclear here. Each apache child/process will open 2 connections, > one for > Apache::DBI and one for DBIx::Class or DBIx::Connector. DBIx::Connector disables Apache::DBI, so there should only be one. If not, there's a bug. Also, most folks who use DBIx::Connector don't use Apache::DBI at all. > Possibly more connections if > a variety of different modules are being used, each with it's own connection > handling. Yes, that's a risk. Don't do that. > This explains an issue I saw with a client 2 months ago where the number of > open database > sessions doubled with the introduction of some new code based on DBIx::Class. Sounds like a bug in DBIx::Class. > I believed the doubling of sessions was a symptom of poor code. Neither I nor > their > developers had any idea that Apache::DBI was being bypassed. Luckily it was a > prototype > and the issue was caught while stress testing in their staging environment. Yes, DBIx::Class should disable Apache::DBI when it does its connecting, just like DBIx::Connector does. Apache::DBI should still be usable if you're connecting by some means other than DBIx::Class. But this is one of the three raisons d'être for DBIx::Connector: Use it to connect instead of the DBI and do your own connection caching. I believe DBIx::Class will be switching to DBIx::Connector eventually. > And so into the design and philosophy. As an admin I need to be able to > deploy code without > side effects that may adversely affect other processes or the system itself. Yeah, that's exactly the complaint about Apache::DBI. Its entire purpose is side-effects. > Now at least you document your connection logic, so that if I do a quick > review I can see the > implications (I doubt I would actually catch it but at least you are giving > me a chance :) > whereas for DBIx::Class, if there is documentation about connecting I don't > know where it is. Yeah, I had to do some mining to dig it out for DBIx::Connector. > Even so, I believe the logic should be > if Apache::DBI use it > else use my stuff IIRC, I can't use Apache::DBI and still support the ability to reconnect when a database connection has dropped. That's its second raison d'être (pings mostly go away when you use it in fixup mode, which is recommended). > I do not know the internals of DBI or the derived classes so I do not know if > the above is > practical. However, it is respectful of the environment it is going to run > in. Writing code > that specifically ignores how a system is configured is ... impolite! Well, one could interpret Apache::DBI as doing exactly the same thing. Someone loads it unbeknownst to you, and all of a sudden the behavior of DBI->connect is globally changed.
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
On Jun 27, 2011, at 1:13 PM, Fred Moyer wrote: > Wow, that's obnoxious: > > 1237 if ($INC{'Apache/DBI.pm'} && $ENV{MOD_PERL}) { > 1238 $old_connect_via = $DBI::connect_via; > 1239 $DBI::connect_via = 'connect'; > 1240 } DBIx::Connector does the same thing. > And it is also apparently not working as they expected: > > [Mon Jun 27 13:05:17 2011] [notice] Apache/2.2.17 (Unix) > mod_apreq2-20090110/2.8.0 mod_perl/2.0.5 Perl/v5.12.3 configured -- > resuming normal operations > 8879 Apache::DBI new connect to 'dbname='... > > In my startup.pl (My::Model is DBIx::Class based): > > $Apache::DBI::DEBUG = 2; > my $db_connect_params = My::Model->connect_params; > Apache::DBI->connect_on_init( @{$db_connect_params} ); > Apache::DBI->setPingTimeOut( $db_connect_params->[0], 5 ); > > # delete this line and I will beat you with a stick (note to self) > My::Model->connect->disconnect; > $DBI::connect_via = 'Apache::DBI::connect'; You lost me. But really, I strongly recommend against the use of Apache::DBI. Some discussion here: http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description Best, David
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
On 27/06/11 02:22 PM, David E. Wheeler wrote: On Jun 27, 2011, at 1:13 PM, Fred Moyer wrote: Snip . You lost me. But really, I strongly recommend against the use of Apache::DBI. Some discussion here: http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description And having read that, I strongly recommend against the use of DBIx-Connector. But then I'm just a production DBA :) Dave -- Dave Morgan Operations Manager, BorealEscapes http://www.borealescapes.ca dave.mor...@borealescapes.ca 403 288 8759
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
On Mon, Jun 27, 2011 at 1:22 PM, David E. Wheeler wrote: > On Jun 27, 2011, at 1:13 PM, Fred Moyer wrote: > >> Wow, that's obnoxious: >> >> 1237 if ($INC{'Apache/DBI.pm'} && $ENV{MOD_PERL}) { >> 1238 $old_connect_via = $DBI::connect_via; >> 1239 $DBI::connect_via = 'connect'; >> 1240 } > > DBIx::Connector does the same thing. I just filed an RT ticket with DBIx::Class for this asking for some details on why it is necessary. Hoping that they'll be willing to share some of their technical concerns. I'm not sure why this code isn't working in my environment, but it could be because I have Apache::DBI setup differently than they do. > You lost me. But really, I strongly recommend against the use of Apache::DBI. > Some discussion here: > http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description It seems like you are looking for a more feature rich db connection caching module as opposed to a drop in module for mod_perl. For most mod_perl users, Apache::DBI provides a performance improvement with Pg and Oracle for just a few lines in your startup.pl.
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
On Jun 27, 2011, at 1:40 PM, Dave Morgan wrote: >> You lost me. But really, I strongly recommend against the use of >> Apache::DBI. Some discussion here: >> >> >> http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description >> > > And having read that, I strongly recommend against the use of DBIx-Connector. > But then I'm just a production DBA :) Me too. What weaknesses do you see in it? Best, David
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
On Jun 27, 2011, at 2:17 PM, Fred Moyer wrote: >> You lost me. But really, I strongly recommend against the use of >> Apache::DBI. Some discussion here: >> http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description > > It seems like you are looking for a more feature rich db connection > caching module as opposed to a drop in module for mod_perl. For most > mod_perl users, Apache::DBI provides a performance improvement with Pg > and Oracle for just a few lines in your startup.pl. No. DBIx::Connector doesn't do caching at all. That's the point, really. Best, David
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
On 27/06/11 04:27 PM, David E. Wheeler wrote: On Jun 27, 2011, at 1:40 PM, Dave Morgan wrote: You lost me. But really, I strongly recommend against the use of Apache::DBI. Some discussion here: http://search.cpan.org/dist/DBIx-Connector/lib/DBIx/Connector.pm#Description And having read that, I strongly recommend against the use of DBIx-Connector. But then I'm just a production DBA :) Me too. What weaknesses do you see in it? What's the point of it? As far as I can see the author claims to have issues with Apache::DBI and does not like the hidden aspect. I have never experienced his "issues" and the hidden aspect is the good part. Apache::DBI can be deployed by an admin without consulting the developers, without affecting their code. It does not require any "use" statements in the source code. He claims that it does no caching across threads. Why not? If the thread uses the same connection/session state then why not use a cached connection. If it doesn't then it is the developers responsibility. Transaction management: I cannot see the point of it, however, I can see the utility to others. My personal viewpoint is that a if good commit, else rollback make what's happening explicit which when dealing with a db is extremely useful. Mind you I believe AutoCommit is a bad thing and should never have been made. My shop also use stored procs for almost everything. Wish DBD::Pg would let me read cursors, like DBD::Oracle, that's what I really need. I suppose it is all a matter of personal preference but I have found that the further removed the developer is from the database the worse they are at accessing it. DBIx::Class is the perfect example. Please spare me the hassle of trying to debug/explain/improve any code that uses that. I am sure that high quality code can be written using DBIx::Class but I have yet to see it. Oops, just realized you are the author :). Please don't take anything above personally, I just think that if you wanted transaction management, it would have been better to write a module that just does that and nothing else. Then, if a developer in my shop wanted to use it I could load it without having to worry about apache managing two connection pools. IMHO, worth exactly what you paid for it Dave Best, David -- Dave Morgan Operations Manager, BorealEscapes http://www.borealescapes.ca dave.mor...@borealescapes.ca 403 288 8759
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
Please calm down, folks. Apache::DBI is a module that was designed to help with porting legacy CGI applications to mod_perl. It's a valid criticism to say that the action-at-a-distance parts of it are undesirable in new mod_perl applications. Personally, I have used mostly custom caching code instead for years. Over time, Apache::DBI picked up some other features which are useful in mod_perl. If you're using something else, you should make sure you have these or know why you don't need them. - Startup safety. This prevents sharing of connections opened in the parent process during startup. Apache::DBI does this by not caching connections during startup. DBIx::Class does this by making a new connection if you fork or start a new thread. Note the stuff about InactiveDestroy in the DBI docs if you use DBIx::Class or DBIx::Connector. - Automatic rollback. Apache::DBI issues a rollback at the end of every request where the DBI connection was not opened in AutoCommit mode. This is to prevent a die() during a transaction from leaving your database in a bad state. If you use subroutine blocks wrapped in eval (e.g. the transaction stuff in DBIx::Connector), this should not be necessary, but make sure you ALWAYS do it that way if you're counting on that to protect you. I agree that trashing Apache::DBI is not very useful, but you should also know what Apache::DBI was meant for and what it's limitations are. - Perrin
Re: Apache::DBI and DBIx::Class [was Re: How do you use mod_perl for your web application?]
On Jun 27, 2011, at 4:20 PM, Dave Morgan wrote: > What's the point of it? First of all, what Perrin said. :-) > As far as I can see the author claims to have issues with Apache::DBI and > does not > like the hidden aspect. FWIW, I am the author. > I have never experienced his "issues" and the hidden > aspect is the good part. Apache::DBI can be deployed by an admin without > consulting the developers, without affecting their code. It does not require > any "use" statements in the source code. Yeah, too magical. I removed support for it in Bricolage years ago, though I can't remember the details of why anymore. connect_cached() worked much better for me (though it's kind of a PITA to set up). > He claims that it does no caching across threads. Why not? If the thread uses > the same connection/session state then why not use a cached connection. If > it doesn't then it is the developers responsibility. Most database handles are not thread-safe. > Transaction management: I cannot see the point of it, however, I can see the > utility to others. My personal viewpoint is that a > if good commit, else rollback > make what's happening explicit which when dealing with a db is extremely > useful. Yeah, that interface is a convenience. I think it's much nicer to scope things within a subref. > Mind you I believe AutoCommit is a bad thing and should never have been made. I don't think AutoCommit was a mistake. These days I always connect with AutoConnect explicitly set to true, as otherwise I might have a transaction running for a long time until the first connection comes in. > My shop also use stored procs for almost everything. Wish DBD::Pg would let > me read cursors, like DBD::Oracle, that's what I really need. I don't understand. PostgreSQL supports cursors, and you can read from them using FETCH. http://www.postgresql.org/docs/current/static/sql-fetch.html Might be my lack of knowledge of Oracle at work here, though. > I suppose it is all a matter of personal preference but I have found that the > further removed the developer is from the database the worse they are at > accessing > it. DBIx::Class is the perfect example. Please spare me the hassle of trying > to debug/explain/improve any code that uses that. I am sure that high quality > code can be written using DBIx::Class but I have yet to see it. Yes, I'm not a fan of ORMs because they tend to create bad queries, among other things. This is why DBIx::Connector is much more focused on adding interfaces to a connection, and not to querying the database. > Oops, just realized you are the author :). :-) > Please don't take anything above > personally, I just think that if you wanted transaction management, it would > have been better to write a module that just does that and nothing else. > Then, if a developer in my shop wanted to use it I could load it without > having to worry about apache managing two connection pools. Well, DBIx::Connector does not do connection pooling (or caching), so that wouldn't be a problem. > IMHO, worth exactly what you paid for it I paid quite a lot of it in terms of my time to develop the interface. So I'm rather fond of it. Varying opinions of course welcome. Best, David