Subject: | DBD::Multiplex does not work correctly with connect_cached when using first_success_random |
When you connect to a Multiplex dsn with a mx_exit_mode of first_success_random, the Multiplex connect() method shuffles the list of database handles, then internally sets the mx_exit_mode to first_success.
The problem is if you connect with a call to connect_cached, then the connect() method in DBD::Multiplex only ever gets called once. But on subsequent calls to DBI::connect_cached, the following code in the $connect_closure of sub connect still gets called:
foreach $a (keys %$attr) {
eval { $dbh->{$a} = $attr->{$a} } or $@ && warn $@;
}
This causes all of the attributes of the database handle to be reset to whatever they were whenever connect() was called the first time. That seems reasonable... any time you connect_cached(), you would not want any state left over from the last time the handle was used.
In the case of DBD::Mutliplex, DBI::connect_cached is being a little too smart, because it is resetting the mx_exit_mode variable back to first_success_random. And since DBD::Multiplex::connect() is never being called again, the exit mode stays that way. Unfortunately, none of the other code knows how to deal with first_success_random, and as a result, produces unexpected behavior.
I suggest the following two things be done:
1) Don't use mx_exit_mode internally. Whenever connect() is called, it should set some other internal-only variable that stores the real exit mode. connect_cached() will only reset variables that were specified when it was invoked, so any internal variables will not be reset.
2) Any place that has an if / elsif block that is checking for the exit mode should have a final else block that is a failure condition when it does not know how to handle the specified exit mode.
If you like this idea and would like me to submit a patch for it, please let me know.
Regards,
-Dan