void na_connpool_init (na_env_t *env) { for (int i=0;i<env->connpool_max;++i) { env->connpool_active.fd_pool[i] = na_target_server_tcpsock_init(); na_target_server_tcpsock_setup(env->connpool_active.fd_pool[i], true); if (env->connpool_active.fd_pool[i] <= 0) { NA_DIE_WITH_ERROR(env, NA_ERROR_INVALID_FD); } } }
void na_connpool_switch (na_env_t *env) { na_connpool_t *connpool; if (env->is_refused_active) { na_connpool_deactivate(&env->connpool_active); connpool = &env->connpool_backup; } else { na_connpool_deactivate(&env->connpool_backup); connpool = &env->connpool_active; } for (int i=0;i<env->connpool_max;++i) { connpool->fd_pool[i] = na_target_server_tcpsock_init(); na_target_server_tcpsock_setup(connpool->fd_pool[i], true); if (connpool->fd_pool[i] <= 0) { NA_DIE_WITH_ERROR(env, NA_ERROR_INVALID_FD); } } }
void na_hc_callback (EV_P_ ev_timer *w, int revents) { int tsfd; int th_ret; na_env_t *env; th_ret = 0; env = (na_env_t *)w->data; if (SigExit == 1) { pthread_exit(&th_ret); return; } pthread_rwlock_rdlock(&LockReconf); pthread_mutex_lock(&env->lock_error_count); if (env->error_count_max > 0 && (env->error_count > env->error_count_max)) { na_hc_event_set(EV_A_ w, revents); env->error_count = 0; pthread_mutex_unlock(&env->lock_error_count); goto unlock_reconf; } pthread_mutex_unlock(&env->lock_error_count); tsfd = na_target_server_tcpsock_init(); if (tsfd <= 0) { na_hc_event_set(EV_A_ w, revents); na_error_count_up(env); NA_STDERR_MESSAGE(NA_ERROR_INVALID_FD); goto unlock_reconf; } na_target_server_hcsock_setup(tsfd); // health check if (!na_server_connect(tsfd, &env->target_server.addr)) { if (!env->is_refused_active) { if (errno != EINPROGRESS && errno != EALREADY) { pthread_rwlock_wrlock(&env->lock_refused); env->is_refused_accept = true; env->is_refused_active = true; pthread_mutex_lock(&env->lock_connpool); na_connpool_switch(env); pthread_mutex_unlock(&env->lock_connpool); pthread_mutex_lock(&env->lock_current_conn); env->current_conn = 0; pthread_mutex_unlock(&env->lock_current_conn); env->is_refused_accept = false; pthread_rwlock_unlock(&env->lock_refused); NA_STDERR("switch backup server"); } } } else { if (env->is_refused_active && na_hc_test_request(tsfd)) { pthread_rwlock_wrlock(&env->lock_refused); env->is_refused_accept = true; env->is_refused_active = false; pthread_mutex_lock(&env->lock_connpool); na_connpool_switch(env); pthread_mutex_unlock(&env->lock_connpool); pthread_mutex_lock(&env->lock_current_conn); env->current_conn = 0; pthread_mutex_unlock(&env->lock_current_conn); env->is_refused_accept = false; pthread_rwlock_unlock(&env->lock_refused); NA_STDERR("switch target server"); } else { if (!env->is_refused_active && !na_hc_test_request(tsfd)) { pthread_rwlock_wrlock(&env->lock_refused); env->is_refused_accept = true; env->is_refused_active = true; pthread_mutex_lock(&env->lock_connpool); na_connpool_switch(env); pthread_mutex_unlock(&env->lock_connpool); pthread_mutex_lock(&env->lock_current_conn); env->current_conn = 0; pthread_mutex_unlock(&env->lock_current_conn); env->is_refused_accept = false; pthread_rwlock_unlock(&env->lock_refused); NA_STDERR("switch backup server"); } } } close(tsfd); na_hc_event_set(EV_A_ w, revents); unlock_reconf: pthread_rwlock_unlock(&LockReconf); }