diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2008-08-06 00:07:07 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2008-08-06 00:07:07 +0100 | 
| commit | 280e655722c8660ec2dff9b08f82b10d5559bfd9 (patch) | |
| tree | 9343c9649ab1f642956b999d1fd37dd2464f6085 | |
| parent | d84e2a93feae8db909dfbe63b55066cb4e8160dc (diff) | |
Simple exponential backoff code. Have to add a maximum delay setting,
something like 5*5<300: 5s, multiply by 5 on each failure, but stop
increasing once we hit 5m.
| -rw-r--r-- | account.c | 36 | ||||
| -rw-r--r-- | account.h | 3 | ||||
| -rw-r--r-- | irc.c | 2 | ||||
| -rw-r--r-- | protocols/nogaim.c | 6 | 
4 files changed, 45 insertions, 2 deletions
| @@ -233,3 +233,39 @@ void account_off( irc_t *irc, account_t *a )  		cancel_auto_reconnect( a );  	}  } + +char *set_eval_account_reconnect_delay( set_t *set, char *value ) +{ +	int start; +	char op; +	int step; +	 +	if( sscanf( value, "%d%c%d", &start, &op, &step ) == 3 && +	    step > 0 && ( op == '+' || op == '*' ) ) +		return value; +	else +		return set_eval_int( set, value ); +} + +int account_reconnect_delay( account_t *a ) +{ +	char *setting = set_getstr( &a->irc->set, "auto_reconnect_delay" ); +	int start, step; +	char op; +	 +	if( sscanf( setting, "%d%c%d", &start, &op, &step ) == 3 && step > 0 ) +	{ +		if( a->auto_reconnect_delay == 0 ) +			return a->auto_reconnect_delay = start; +		else if( op == '+' ) +			return a->auto_reconnect_delay += step; +		else if( op == '*' ) +			return a->auto_reconnect_delay *= step; +	} +	else if( sscanf( setting, "%d", &start ) == 1 ) +	{ +		return a->auto_reconnect_delay = start; +	} +	 +	return 0; +} @@ -34,6 +34,7 @@ typedef struct account  	char *server;  	int auto_connect; +	int auto_reconnect_delay;  	int reconnect;  	set_t *set; @@ -51,6 +52,8 @@ void account_on( irc_t *irc, account_t *a );  void account_off( irc_t *irc, account_t *a );  char *set_eval_account( set_t *set, char *value ); +char *set_eval_account_reconnect_delay( set_t *set, char *value ); +int account_reconnect_delay( account_t *a );  #define ACC_SET_NOSAVE		1  #define ACC_SET_OFFLINE_ONLY	2 @@ -138,7 +138,7 @@ irc_t *irc_new( int fd )  	set_add( &irc->set, "away_devoice", "true",  set_eval_away_devoice, irc );  	set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );  	set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); -	set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc ); +	set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_account_reconnect_delay, irc );  	set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );  	set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );  	set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 7466e93a..eb3fc2ad 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -266,6 +266,10 @@ void imcb_connected( struct im_connection *ic )  	/* Also necessary when we're not away, at least for some of the  	   protocols. */  	imc_set_away( ic, u->away ); +	 +	/* Apparently we're connected successfully, so reset the +	   exponential backoff timer. */ +	ic->acc->auto_reconnect_delay = 0;  }  gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ) @@ -330,7 +334,7 @@ void imc_logout( struct im_connection *ic, int allow_reconnect )  	else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) &&  	         set_getbool( &a->set, "auto_reconnect" ) )  	{ -		int delay = set_getint( &irc->set, "auto_reconnect_delay" ); +		int delay = account_reconnect_delay( a );  		imcb_log( ic, "Reconnecting in %d seconds..", delay );  		a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a ); | 
