@ -122,6 +122,8 @@ struct proxy_instance {
typedef struct proxy_instance proxy_instance_t ;
typedef struct proxy_instance proxy_instance_t ;
static ckmsgq_t * srvchk ; // Server check message queue
static bool server_alive ( ckpool_t * ckp , server_instance_t * si , bool pinging )
static bool server_alive ( ckpool_t * ckp , server_instance_t * si , bool pinging )
{
{
char * userpass = NULL ;
char * userpass = NULL ;
@ -252,6 +254,8 @@ reconnect:
}
}
retry :
retry :
ckmsgq_add ( srvchk , si ) ;
do {
do {
selret = wait_read_select ( us - > sockd , 5 ) ;
selret = wait_read_select ( us - > sockd , 5 ) ;
if ( ! selret & & ! ping_main ( ckp ) ) {
if ( ! selret & & ! ping_main ( ckp ) ) {
@ -344,6 +348,8 @@ retry:
send_unix_msg ( sockd , " true " ) ;
send_unix_msg ( sockd , " true " ) ;
else
else
send_unix_msg ( sockd , " false " ) ;
send_unix_msg ( sockd , " false " ) ;
} else if ( cmdmatch ( buf , " fallback " ) ) {
goto reconnect ;
} else if ( cmdmatch ( buf , " loglevel " ) ) {
} else if ( cmdmatch ( buf , " loglevel " ) ) {
sscanf ( buf , " loglevel=%d " , & ckp - > loglevel ) ;
sscanf ( buf , " loglevel=%d " , & ckp - > loglevel ) ;
} else if ( cmdmatch ( buf , " ping " ) ) {
} else if ( cmdmatch ( buf , " ping " ) ) {
@ -1464,6 +1470,8 @@ retry:
LOGWARNING ( " Block rejected locally. " ) ;
LOGWARNING ( " Block rejected locally. " ) ;
} else
} else
LOGNOTICE ( " No backup btcd to send block to ourselves " ) ;
LOGNOTICE ( " No backup btcd to send block to ourselves " ) ;
} else if ( cmdmatch ( buf , " fallback " ) ) {
goto reconnect ;
} else if ( cmdmatch ( buf , " loglevel " ) ) {
} else if ( cmdmatch ( buf , " loglevel " ) ) {
sscanf ( buf , " loglevel=%d " , & ckp - > loglevel ) ;
sscanf ( buf , " loglevel=%d " , & ckp - > loglevel ) ;
} else if ( cmdmatch ( buf , " ping " ) ) {
} else if ( cmdmatch ( buf , " ping " ) ) {
@ -1617,6 +1625,51 @@ static int proxy_mode(ckpool_t *ckp, proc_instance_t *pi)
return ret ;
return ret ;
}
}
/* Tell the watchdog what the current server instance is and decide if we
* should check to see if the higher priority servers are alive and fallback */
static void server_watchdog ( ckpool_t * ckp , server_instance_t * cursi )
{
static time_t last_t = 0 ;
bool alive = false ;
time_t now_t ;
int i , srvs ;
/* Rate limit to checking only once every 5 seconds */
now_t = time ( NULL ) ;
if ( now_t < = last_t + 5 )
return ;
last_t = now_t ;
/* Is this the highest priority server already? */
if ( cursi = = ckp - > servers [ 0 ] )
return ;
if ( ckp - > proxy )
srvs = ckp - > proxies ;
else
srvs = ckp - > btcds ;
for ( i = 0 ; i < srvs ; i + + ) {
server_instance_t * si = ckp - > servers [ i ] ;
/* Have we reached the current server? */
if ( si = = cursi )
return ;
if ( ckp - > proxy ) {
proxy_instance_t * proxi = si - > data ;
connsock_t * cs = proxi - > cs ;
alive = proxy_alive ( ckp , si , proxi , cs , true ) ;
} else
alive = server_alive ( ckp , si , true ) ;
if ( alive )
break ;
}
if ( alive )
send_proc ( ckp - > generator , " fallback " ) ;
}
int generator ( proc_instance_t * pi )
int generator ( proc_instance_t * pi )
{
{
ckpool_t * ckp = pi - > ckp ;
ckpool_t * ckp = pi - > ckp ;
@ -1624,6 +1677,8 @@ int generator(proc_instance_t *pi)
LOGWARNING ( " %s generator starting " , ckp - > name ) ;
LOGWARNING ( " %s generator starting " , ckp - > name ) ;
srvchk = create_ckmsgq ( ckp , " srvchk " , & server_watchdog ) ;
if ( ckp - > proxy )
if ( ckp - > proxy )
ret = proxy_mode ( ckp , pi ) ;
ret = proxy_mode ( ckp , pi ) ;
else
else