280cbbaf8ebd0fed85ffad886b8aa14de03341ea max Mon Jan 20 04:49:57 2014 -0800 Changing handling of sqlConnect to allow a db that exists onlyon the failover server, not on the main one. diff --git src/hg/lib/jksql.c src/hg/lib/jksql.c index c3fd729..d3d1fb1 100644 --- src/hg/lib/jksql.c +++ src/hg/lib/jksql.c @@ -271,30 +271,41 @@ * - if there is no profile named the same as the database, use * the default profile of "db" * return NULL if not found. */ { //assert((profileName != NULL) || (database != NULL)); if (profiles == NULL) sqlProfileLoad(); if (profileName != NULL) return sqlProfileFindByName(profileName, database); else return sqlProfileFindByDatabase(database); } +static struct sqlProfile* sqlProfileGetFailover(struct sqlProfile* sp, char *database) +/* try to find a failover slow-x profile for a profile x */ +{ +if (sp==NULL || sp->name==NULL) + return NULL; +char *slowProfName = catTwoStrings("slow-", sp->name); +struct sqlProfile *slow = sqlProfileGet(slowProfName, database); +freez(&slowProfName); +return slow; +} + static struct sqlProfile* sqlProfileMustGet(char *profileName, char *database) /* lookup a profile using the profile resolution algorithm or die trying */ { struct sqlProfile* sp = sqlProfileGet(profileName, database); if (sp == NULL) { if (profileName == NULL) errAbort("can't find database %s in hg.conf, should have a default named \"db\"", database); else if (database == NULL) errAbort("can't find profile %s in hg.conf", profileName); else errAbort("can't find profile %s for database %s in hg.conf", profileName, database); } return sp; @@ -926,46 +937,58 @@ return sqlConnRemote(host, 0, NULL, user, password, database, TRUE); } struct sqlConnection *sqlMayConnectRemote(char *host, char *user, char *password, char *database) /* Connect to database somewhere as somebody. Database maybe NULL to * just connect to the server. Return NULL can't connect */ { return sqlConnRemote(host, 0, NULL, user, password, database, FALSE); } static struct sqlConnection *sqlConnProfile(struct sqlProfile* sp, char *database, boolean abort) /* Connect to database using the profile. Database maybe NULL to connect to * the server. Optionally abort on failure. */ { +bool mainAbort = abort; struct sqlConnection *sc; -// connect with the default profile -sc = sqlConnRemote(sp->host, sp->port, sp->socket, sp->user, sp->password, database, abort); -if (sc!=NULL) - sc->profile = sp; // remember the profile +// get the slow-db profile for the profile, if it exists +struct sqlProfile *slow = sqlProfileGetFailover(sp, database); +// if we have a failover profile, don't abort right away +if (slow!=NULL) + mainAbort = FALSE; -// optionally prepare the slower failover connection -if (sp->name==NULL) +// connect with the default profile +sc = sqlConnRemote(sp->host, sp->port, sp->socket, sp->user, sp->password, database, mainAbort); +if (slow==NULL) + // the default case: just return sc, can be NULL return sc; -char *slowProfName = catTwoStrings("slow-", sp->name); -struct sqlProfile *slow = sqlProfileGet(slowProfName, database); -freez(&slowProfName); -if (slow==NULL) +// we still have a failover profile to setup +if (sc==NULL) + { + // We have a failover connection configured, but no main connection. + // This can happen if the requested database exists only on the failover connection + // We only create a failover connection in this case and return it as the main one + sc = sqlConnRemote(slow->host, slow->port, slow->socket, slow->user, slow->password, database, abort); + if (monitorFlags & JKSQL_TRACE) + fprintf(stderr, "SQL_FAILOVER_AT_CONNECT"); return sc; + } + +sc->profile = sp; // remember the profile // don't connect the slow connection yet: lazily connect later when needed; saves 0.5 // seconds per connection on transatlantic links // instead create a "placeholder" sqlConnection with all connection data, but no connection struct sqlConnection *slowSc; AllocVar(slowSc); slowSc->profile = slow; // remember the profile slowSc->db = database; slowSc->hasTableCache = -1; sc->slowConn = slowSc; return sc; } struct sqlConnection *sqlMayConnect(char *database) /* Connect to database on default host as default user.