/* Do not remove the headers from this file! see /USAGE for more info. */ /* ** reconnect.c -- provide reconnection logic for socket users ** ** 95-May-11. Deathblade. Created. */ /* ** The client should fill in this function with the reconnection callback. ** The function prototype is: void func(string key) */ nosave function reconn_func; /* ** Store the retry time for each key as we try to reestablish contact. ** key -> ({ period, count }). If a key has an entry here, then we are ** attempting to establish contact. */ nosave private mapping retry_info = ([ ]); #define MAX_RETRY_PERIOD 3600 /* one hour */ #define RETRY_PER_PERIOD 4 /* 4 retries at each time period */ private nomask void time_to_reconnect(string key) { /* ** If the connection was successful and the retry data was cleared, ** then just return. */ if ( !retry_info[key] ) return; evaluate(reconn_func, key); } protected nomask void cancel_reconnection(string key) { map_delete(retry_info, key); } protected nomask void trigger_reconnect(string key) { int delay; /* ** Attempt to reconnect to the target. If we are not in the process ** of retrying, then set up the retry with a 1-minute period and begin ** immediately. ** ** If we have been retrying and we've hit the max # retries for this ** time period, then double the time period and schedule a retry. */ if ( !retry_info[key] ) { retry_info[key] = ({ 60, 0 }); delay = 0; } else if ( ++retry_info[key][1] == RETRY_PER_PERIOD ) { delay = retry_info[key][0] * 2; if ( delay > MAX_RETRY_PERIOD ) delay = MAX_RETRY_PERIOD; retry_info[key] = ({ delay, 0 }); } else delay = retry_info[key][0]; call_out((: time_to_reconnect :), delay, key); } string stat_me() { return sprintf("\nRETRY INFO\n%O\n", retry_info); }