From: Alan T. DeKok Date: Mon, 17 Oct 2011 19:18:56 +0000 (+0200) Subject: Clean up spare connections on release X-Git-Tag: release_3_0_0_beta0~579 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa41e2b666d6548d9c63ea06a9148eaa8d07e07f;p=thirdparty%2Ffreeradius-server.git Clean up spare connections on release This mirrors the "spawn new connections on get" functionality. Also, remember when we last failed to connect. When that happens, we continue to use existing connections, but we don't open new connections for one second. This behavior ensures that incoming requests will still be processed quickly, even when the back-end database is down. --- diff --git a/src/main/connection.c b/src/main/connection.c index 9f8a1cf6cf4..39dcfdf8adf 100644 --- a/src/main/connection.c +++ b/src/main/connection.c @@ -58,6 +58,7 @@ struct fr_connection_pool_t { time_t last_checked; time_t last_spawned; + time_t last_failed; time_t last_complained; int max_uses; @@ -156,6 +157,8 @@ static fr_connection_t *fr_connection_spawn(fr_connection_pool_t *fc, rad_assert(fc != NULL); rad_assert(fc->num <= fc->max); + if (fc->last_failed == now) return NULL; + this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); @@ -167,6 +170,7 @@ static fr_connection_t *fr_connection_spawn(fr_connection_pool_t *fc, */ conn = fc->create(fc->ctx); if (!conn) { + fc->last_failed = now; free(this); return NULL; } @@ -322,7 +326,7 @@ static int fr_connection_manage(fr_connection_pool_t *fc, rad_assert(this != NULL); /* - * Don't terminated reserved connections + * Don't terminated in-use connections */ if (this->used) return 1; @@ -357,7 +361,7 @@ static int fr_connection_pool_check(fr_connection_pool_t *fc) time_t now = time(NULL); fr_connection_t *this; - if (now == fc->last_checked) return 1; + if (fc->last_checked == now) return 1; pthread_mutex_lock(&fc->mutex); @@ -425,16 +429,18 @@ int fr_connection_check(fr_connection_pool_t *fc, void *conn) { int rcode = 1; fr_connection_t *this; - + time_t now; + if (!fc) return 1; if (!conn) return fr_connection_pool_check(fc); + now = time(NULL); pthread_mutex_lock(&fc->mutex); for (this = fc->head; this != NULL; this = this->next) { if (this->connection == conn) { - rcode = fr_connection_manage(fc, conn, time(NULL)); + rcode = fr_connection_manage(fc, conn, now); break; } } @@ -523,8 +529,21 @@ void fr_connection_release(fr_connection_pool_t *fc, void *conn) } } - pthread_mutex_unlock(&fc->mutex); - + + /* + * We mirror the "spawn on get" functionality by having + * "delete on release". If there are too many spare + * connections, go manage the pool && clean some up. + */ + if ((time(NULL) >= (fc->last_spawned + fc->cleanup_delay)) && + ((fc->num - fc->active) > fc->spare)) { + pthread_mutex_unlock(&fc->mutex); + + fr_connection_pool_check(fc); + } else { + pthread_mutex_unlock(&fc->mutex); + } + DEBUG("%s: Released connection (%i)", fc->log_prefix, this->number); }