Verified Commit 26587875 authored by Grigorii Demidov's avatar Grigorii Demidov Committed by Petr Špaček

lib/nsrep: don't mark NS as 'timeouted' immediately, but after two retries

parent 299e605b
......@@ -1077,8 +1077,8 @@ static int session_tls_hs_cb(struct session *session, int status)
int deletion_res = worker_del_tcp_waiting(worker, &peer->ip);
if (status) {
kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_TIMEOUT,
worker->engine->resolver.cache_rtt, KR_NS_RESET);
kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_DEAD,
worker->engine->resolver.cache_rtt, KR_NS_UPDATE);
} else {
if (deletion_res != 0) {
/* session isn't in list of waiting queries, *
......@@ -1244,8 +1244,8 @@ static void on_tcp_connect_timeout(uv_timer_t *timer)
VERBOSE_MSG(qry, "=> connection to '%s' failed\n", addr_str);
}
kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_TIMEOUT,
worker->engine->resolver.cache_rtt, KR_NS_RESET);
kr_nsrep_update_rtt(NULL, &peer->ip, KR_NS_DEAD,
worker->engine->resolver.cache_rtt, KR_NS_UPDATE);
while (session->waiting.len > 0) {
struct qr_task *task = session->waiting.at[0];
......@@ -1327,8 +1327,8 @@ static void on_udp_timeout(uv_timer_t *timer)
inet_ntop(choice->sa_family, kr_inaddr(choice), addr_str, sizeof(addr_str));
VERBOSE_MSG(qry, "=> server: '%s' flagged as 'bad'\n", addr_str);
}
kr_nsrep_update_rtt(&qry->ns, choice, KR_NS_TIMEOUT,
worker->engine->resolver.cache_rtt, KR_NS_RESET);
kr_nsrep_update_rtt(&qry->ns, choice, KR_NS_DEAD,
worker->engine->resolver.cache_rtt, KR_NS_UPDATE);
}
}
task->timeouts += 1;
......
......@@ -280,7 +280,7 @@ int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx)
int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
unsigned score, kr_nsrep_lru_t *cache, int umode)
{
if (!cache) {
if (!cache || umode > KR_NS_MAX) {
return kr_error(EINVAL);
}
......@@ -309,10 +309,6 @@ int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
if (!cur) {
return kr_ok();
}
/* Score limits */
if (score > KR_NS_MAX_SCORE) {
score = KR_NS_MAX_SCORE;
}
if (score <= KR_NS_GLUED) {
score = KR_NS_GLUED + 1;
}
......@@ -320,14 +316,20 @@ int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr,
if (*cur == 0) {
umode = KR_NS_RESET;
}
unsigned new_score = 0;
/* Update score, by default smooth over last two measurements. */
switch (umode) {
case KR_NS_UPDATE: *cur = (*cur + score) / 2; break;
case KR_NS_RESET: *cur = score; break;
case KR_NS_ADD: *cur = MIN(KR_NS_MAX_SCORE - 1, *cur + score); break;
case KR_NS_MAX: *cur = MAX(*cur, score); break;
case KR_NS_UPDATE: new_score = (*cur + score) / 2; break;
case KR_NS_RESET: new_score = score; break;
case KR_NS_ADD: new_score = MIN(KR_NS_MAX_SCORE - 1, *cur + score); break;
case KR_NS_MAX: new_score = MAX(*cur, score); break;
default: break;
}
/* Score limits */
if (new_score > KR_NS_MAX_SCORE) {
new_score = KR_NS_MAX_SCORE;
}
*cur = new_score;
return kr_ok();
}
......
......@@ -40,6 +40,11 @@ enum kr_ns_score {
KR_NS_GLUED = 10
};
/**
* See kr_nsrep_update_rtt()
*/
#define KR_NS_DEAD ((KR_NS_TIMEOUT * 4) / 3)
/**
* NS QoS flags.
*/
......@@ -117,6 +122,8 @@ int kr_nsrep_elect_addr(struct kr_query *qry, struct kr_context *ctx);
* @param ns updated NS representation
* @param addr chosen address (NULL for first)
* @param score new score (i.e. RTT), see enum kr_ns_score
* after two calls with score = KR_NS_DEAD and umode = KR_NS_UPDATE
* server will be guaranteed to have KR_NS_TIMEOUTED score
* @param cache LRU cache
* @param umode update mode (KR_NS_UPDATE or KR_NS_RESET or KR_NS_ADD)
* @return 0 on success, error code on failure
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment