I recall seeing something on CPAN awhile back that might provide either an interim solution or a starting point for working this into the DBIx::Class core functionality. All I can come up with now is DBIx::DBCluster (not sure if this is what I'm remembering or not).
<br><br>DISCLAIMER: I've not used this module, it's not had any activity since its first release in June 2003 and is prominantly labeled as 'beta' code. <br><br>It claims to be a drop-in replacement for DBI that dynamically chooses from an array of read-only and read-write DSN's for the appropriate SQL statements. The documentation is pretty sparse so you'd need to grok the source code to see the implementation details.
<br><br>FWIW<br><br>Brian<br><br><div><span class="gmail_quote">On 5/2/06, <b class="gmail_sendername">Brandon Black</b> <<a href="mailto:blblack@gmail.com">blblack@gmail.com</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On 5/2/06, Matija Grabnar <<a href="mailto:matija@literal.si">matija@literal.si</a>> wrote:<br>> Nathanial Hendler wrote:<br>> > In my situation, I have a setup of one master and many slave databases.<br>> > Each slave is used for reading, and the master is used to write to.
<br>> > Does DBIx::Class support this environment? Can I create a single object<br>> > and interact with it normally and DBIx knows that<br>> > INSERTs/UPDATEs/DELETEs happen on database server A, and SELECTs happen
<br>> > on database server B?<br>> ><br>> > Any suggestions would be appreciated.<br>> ><br>> I don't remember seeing anything like that in any DBIC docs. However, if<br>> you use an explicit schema with your DBIC class, you can have multiple
<br>> "schema handles", each with it's own connection data. So for your<br>> situation, you could have an array of "read-only" schemas and one<br>> "read-write" schema.<br>><br>> Unfortunately, from what I can see, your code would have to decide which
<br>> is appropriate to use when - this level of automation does not seem to<br>> be present in DBIx::Class.<br>><br><br>I was discussing this (and thinking about implementing it) on the DBIC<br>irc channel a little while back, but I've recently dropped off on
<br>public development to dedicate my time to finishing up my main project<br>at my paying $job, and I haven't even been on irc at all lately, so I<br>don't know if anyone else has gone further with the concepts yet or<br>
not.<br><br>This kind of thing would be most readily implemented as a new<br>DBIx::Class::Storage driver/subclass. While the existing<br>DBIx::Class::Storage::DBI is the only/main Storage class in<br>DBIx::Class at the moment, it was designed to be extended (and for
<br>completely orthogonal Storage classes like ::LDAP to be implemented).<br><br>Basically, you'd make a new DBIx::Class::Storage::DBI::Replicated (or<br>whatever name, that's just a random one for the sake of conversation),
<br>and inherit most of the functionality from DBIx::Class::Storage::DBI.<br>You'd override methods where neccesary to support passing multiple<br>sets of connection information into ->connect_info, with some sort of<br>
designation as to which ones are readonly and which ones are readwrite<br>(In the general case, there could be 0->Many of either class of<br>connections, and writing operations should fail if no readwrite<br>connections are defined).
<br><br>Then stick some logic in other overriden areas to do something<br>intelligent to spread the load over multiple servers of the same class<br>(this needs some careful thought, and perhaps some user-defined<br>behavior parameters as well - per-proc/thread (round-robin,
<br>sequential, random?)? round-robin every X requests? etc), support some<br>options like whether to use the readwrite entries as part of the<br>readonly list as well for load-spreading purposes, etc.<br><br>There's also some other things in the underlying existing Storage::DBI
<br>driver that need to be cleaned/tweaked first as well. Things like the<br>fork/thread support being suboptimal. Ideally that should be<br>converted from the current "recheck before doing anything" model to a
<br>more efficient "execute blindly and check for exceptions" model.<br>Those things affect the design of the replica-capable subclass, as it<br>will probably do similar things (but with slightly different behavior)
<br>to failover to other replicas, etc.<br><br>The only pre-check type of thing that can't be handled in an exception<br>style (AFAIK at the moment) is the current "$$ == saved_pid"-thing<br>that's in there for watching forks (because when you fork with an open
<br>DBI connection, DBI actually can continue to work, but will exhibit<br>broken behavior and/or warnings and/or exceptions down the line<br>depending on races and whatnot). Thread changes always trigger<br>exceptions to watch though. After any exception, check validity of
<br>the $dbh (via the current prechecks like ->{ping}, ->{Active}, etc) to<br>decide whether to attempt reconnection and retry of the operation (or<br>replay of the transaction in the case of ->txn_do?, or exception on
<br>the transaction if not) (or failover...) or throw upstream to the DBIC<br>user for general SQL errors always of course.<br><br>I'll eventually get to this if nobody else picks up these things<br>before I get back, but anyone out there who feels up to it, feel free
<br>:)<br><br>-- Brandon<br><br>_______________________________________________<br>List: <a href="http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class">http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class</a>
<br>Wiki: <a href="http://dbix-class.shadowcatsystems.co.uk/">http://dbix-class.shadowcatsystems.co.uk/</a><br>IRC: irc.perl.org#dbix-class<br>SVN: <a href="http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/">http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
</a><br></blockquote></div><br>