syncrepl retry-on-error code

This commit is contained in:
Jong Hyuk Choi 2004-06-18 05:04:03 +00:00
parent 2478fdf2ec
commit 763f8c76ee
4 changed files with 94 additions and 19 deletions

View File

@ -66,12 +66,11 @@ ldap_pvt_runqueue_remove(
break;
}
assert ( e == entry );
LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
if ( e == entry ) {
LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
}
LDAP_FREE( entry );
}
struct re_s*
@ -148,7 +147,7 @@ ldap_pvt_runqueue_resched(
LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
if ( entry->interval.tv_sec && !defer ) {
if ( !defer ) {
entry->next_sched.tv_sec = time( NULL ) + entry->interval.tv_sec;
} else {
entry->next_sched.tv_sec = 0;

View File

@ -3028,6 +3028,9 @@ add_syncrepl(
si->si_attrs[0] = NULL;
si->si_type = LDAP_SYNC_REFRESH_ONLY;
si->si_interval = 86400;
si->si_retryinterval = 0;
si->si_retrynum_init = 0;
si->si_retrynum = 0;
si->si_syncCookie.ctxcsn = NULL;
si->si_syncCookie.octet_str = NULL;
si->si_syncCookie.sid = -1;
@ -3144,6 +3147,8 @@ add_syncrepl(
#define SLIMITSTR "sizelimit"
#define TLIMITSTR "timelimit"
#define RETRYSTR "retry"
#define GOT_ID 0x0001
#define GOT_PROVIDER 0x0002
#define GOT_METHOD 0x0004
@ -3383,6 +3388,53 @@ parse_syncrepl_line(
(long) si->si_interval);
return 1;
}
} else if ( !strncasecmp( cargv[ i ],
RETRYSTR, sizeof( RETRYSTR ) - 1 ) )
{
char *str;
char **retry_list;
int j, k, n;
val = cargv[ i ] + sizeof( RETRYSTR );
retry_list = (char **) ch_calloc( 1, sizeof( char * ));
retry_list[0] = NULL;
str2clist( &retry_list, val, " ,\t" );
for ( k = 0; retry_list && retry_list[k]; k++ ) ;
n = k / 2;
if ( k % 2 ) {
fprintf( stderr,
"Error: incomplete syncrepl retry list\n" );
for ( k = 0; retry_list && retry_list[k]; k++ ) {
ch_free( retry_list[k] );
}
ch_free( retry_list );
exit( EXIT_FAILURE );
}
si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
for ( j = 0; j < n; j++ ) {
si->si_retryinterval[j] = atoi( retry_list[j*2] );
if ( *retry_list[j*2+1] == '+' ) {
si->si_retrynum_init[j] = -1;
si->si_retrynum[j] = -1;
j++;
break;
} else {
si->si_retrynum_init[j] = atoi( retry_list[j*2+1] );
si->si_retrynum[j] = atoi( retry_list[j*2+1] );
}
}
si->si_retrynum_init[j] = -2;
si->si_retrynum[j] = -2;
si->si_retryinterval[j] = 0;
for ( k = 0; retry_list && retry_list[k]; k++ ) {
ch_free( retry_list[k] );
}
ch_free( retry_list );
} else if ( !strncasecmp( cargv[ i ],
MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) )
{

View File

@ -1407,6 +1407,9 @@ typedef struct syncinfo_s {
char **si_attrs;
int si_type;
time_t si_interval;
time_t *si_retryinterval;
int *si_retrynum_init;
int *si_retrynum;
struct sync_cookie si_syncCookie;
int si_manageDSAit;
int si_slimit;

View File

@ -823,6 +823,7 @@ do_syncrepl(
int first = 0;
int dostop = 0;
ber_socket_t s;
int i, defer = 1;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 );
@ -885,7 +886,7 @@ do_syncrepl(
arg );
} else {
connection_client_enable( s );
}
}
} else if ( !first ) {
dostop = 1;
}
@ -901,25 +902,45 @@ do_syncrepl(
* 4) for Persist and Success, reschedule to defer
*/
ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) {
ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask );
}
if ( dostop ) {
connection_client_stop( s );
}
if ( rc && rc != LDAP_SERVER_DOWN ) {
ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
} else {
if ( rc == LDAP_SERVER_DOWN ||
si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
rc = 0;
} else {
rc = 1;
if ( rc == LDAP_SUCCESS ) {
if ( dostop ) {
connection_client_stop( s );
}
if ( si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
defer = 0;
}
rtask->interval.tv_sec = si->si_interval;
ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, defer );
if ( si->si_retrynum ) {
for ( i = 0; si->si_retrynum_init[i] != -2; i++ ) {
si->si_retrynum[i] = si->si_retrynum_init[i];
}
si->si_retrynum[i] = -2;
}
} else {
for ( i = 0; si->si_retrynum && si->si_retrynum[i] <= 0; i++ ) {
if ( si->si_retrynum[i] == -1 || si->si_retrynum[i] == -2 )
break;
}
if ( !si->si_retrynum || si->si_retrynum[i] == -2 ) {
if ( dostop ) {
connection_client_stop( s );
}
ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
} else if ( si->si_retrynum[i] >= -1 ) {
if ( si->si_retrynum[i] > 0 )
si->si_retrynum[i]--;
rtask->interval.tv_sec = si->si_retryinterval[i];
ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
}
ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, rc );
}
ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
return NULL;