[Dbix-class] Problem using DBIC in a Catalyst/mod_perl environment with multiple virtual hosts

Andreas Dembach ad at dg-i.net
Thu Aug 24 02:42:23 CEST 2006


Brandon Black wrote:
>
>
> On 8/22/06, *Andreas Dembach* <ad at dg-i.net <mailto:ad at dg-i.net>> wrote:
>
>
>     Hello list,
>
>     we have the following situation:
>
>     - we are migrating mod_perl application to Catalyst under
>     mod_perl2 and
>     use DBIC as persistence layer.
>     - the apache server hosts two (in fact even more) virtual hosts
>     with the
>     same application but different configurations (e.g. one for test
>     and one
>     for production).
>     - beneath other configuration items, like template-root we want the
>     different virtual hosts to use different database connections.
>
>     Problem:
>
>     As far as I can tell from the source code, DBIx::Class::Storage::DBI
>     caches the database handle in '_dbh' which results in always using the
>     first database handle that inititated a connection. So we end up
>     having
>     the configured $dbh of whatever virtual host  is called first within a
>     newly created Apache process.
>
>     Question:
>
>     Is this a design decision to support only one DB connection per
>     process
>     or is this a little bug that could be fixed by caching the dbh
>     with some
>     additional meta info (e.g. the connection parameters à la
>     DBI->connect_cached)?
>
>
> Skipping the Catalyst part of things and just focusing on DBIx::Class:
> This should be a non-issue as long as you're using schema objects
> rather than schema classes, which is the preferred and recommended way
> to go about things.
yes, you're probably right at this point. actually our application is
not completely a catayst application, but consists of two parts: a
web-frontend (catalyst-based) and a separate business logic layer, which
the catalyst app uses via a defined interface. We are using DBIx::Class
in both parts. In the non-Catalyst part I could verify, that we do not
have the problem here.

Remains the one in the Catalyst::DBIC::Schema :-( 

package web::Model::Data;

use strict;
use base 'Catalyst::Model::DBIC::Schema';

__PACKAGE__->config(
    schema_class => 'web::Schema::IbfData',
    connect_info => [
    sub { some-module->get_dbh; }
    ],
);

I have always the same storage class (with the same dbh) within the
schema, so I guess the sub {} that I'm passing as connect_info is only
called once.

Matt suggested in another post to use ACCEPT_CONTEXT, which seems a good
idea. I tried that and it seems to work but anyway there are two issues
left:

1) I could not figure out how to get rid of the initial connect_info set
by the ->config() call that Cat::DBIC::Schema seems to need during
startup, which annoys a little since I do not have any configuration
information during Apache startup.
2) I have to cache the schema for each database source, otherwise the
schema/storage/whatever seems to just vanish after returning the newly
cloned schema which results in exceptions like "Can't call method
"source" on an undefined value" or "calling execute on disconnected handle".

My Cat Model now looks like this:

==================use base 'Catalyst::Model::DBIC::Schema';

use Helper::Configuration;

__PACKAGE__->config(
    schema_class => 'web::Schema::IbfDaten',
# this here actually does not result in a valid DB connection, because
configuration is not yet determined on server startup
    connect_info => [
      Helper::Configuration->property("db.source"),
      Helper::Configuration->property("db.user"),
      Helper::Configuration->property("db.password"),
    ],
);

my %schema_buffer;

sub ACCEPT_CONTEXT {
      my ( $self, $c, @extra_arguments ) 
   # Now in the request, the DB properties are defined foreach virtual host
    my $datasource     my $user     my $password 
  unless ( defined( $schema_buffer{$$}{$datasource} ) ) {
    my $schema     $schema_buffer{$$}{$datasource}   }
  return $schema_buffer{$$}{$datasource};
}
=================
Well, at least I can move the overriden Storage class to /dev/null now :-)

Thanks for your help,
Andreas
>
> Are you directly accessing the schema class?  Are you using
> Catalyst::Model::DBIC::Schema?  Can you paste/post your Schema and
> Model files, so we can see exactly how you're connecting things?  I
> *think* C::M::DBIC::Schema handles this case correctly, but of course
> there could be a bug or thinko of some kind.
>
> -- Brandon
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> List: http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
> Wiki: http://dbix-class.shadowcatsystems.co.uk/
> IRC: irc.perl.org#dbix-class
> SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
> Searchable Archive: http://www.mail-archive.com/dbix-class@lists.rawmode.org/


-- 
-----------------------------------------------------------------
Dembach Goo Informatik GmbH & Co. KG
Andreas Dembach              fon          +49-221-801 483 0
Rathenauplatz 9              fax          +49-221-801 483 20
D-50674 Cologne              emergency    +49-180-50 50 70 919
Germany                      smtp         ad +at+ dg-i +dot+ net
pgp fingerprint 25C2 8C94 015A E92C 3C67  E9B7 2E39 6FFC 277D 6700 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.rawmode.org/pipermail/dbix-class/attachments/20060824/1ab9be82/attachment-0001.htm 


More information about the Dbix-class mailing list