Commit b459d58c authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Fix the broken logic in the random directors picking routine.

Drop the consistency check for health-changes, at the cost of a
slight bias[1] for hosts before, or after, then one that changed health,
according to how its health changed.

Count all failures to pick against the retry count.

Fixes #361


git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@3359 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 443b0f80
...@@ -66,9 +66,9 @@ struct vdi_random { ...@@ -66,9 +66,9 @@ struct vdi_random {
static struct vbe_conn * static struct vbe_conn *
vdi_random_getfd(struct sess *sp) vdi_random_getfd(struct sess *sp)
{ {
int i, j, k; int i, k;
struct vdi_random *vs; struct vdi_random *vs;
double r, s1, s2; double r, s1;
struct vbe_conn *vbe; struct vbe_conn *vbe;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
...@@ -78,43 +78,32 @@ vdi_random_getfd(struct sess *sp) ...@@ -78,43 +78,32 @@ vdi_random_getfd(struct sess *sp)
k = 0; k = 0;
for (k = 0; k < vs->retries; ) { for (k = 0; k < vs->retries; ) {
r = random() / 2147483648.0; /* 2^31 */ /* Sum up the weights of healty backends */
assert(r >= 0.0 && r < 1.0);
s1 = 0.0; s1 = 0.0;
j = 0; for (i = 0; i < vs->nhosts; i++)
for (i = 0; i < vs->nhosts; i++) { if (vs->hosts[i].backend->healthy)
if (!vs->hosts[i].backend->healthy) s1 += vs->hosts[i].weight;
continue;
s1 += vs->hosts[i].weight;
j++;
}
if (j == 0) /* No healthy hosts */ if (s1 == 0.0)
return (NULL); return (NULL);
/* Pick a random threshold in that interval */
r = random() / 2147483648.0; /* 2^31 */
assert(r >= 0.0 && r < 1.0);
r *= s1; r *= s1;
s2 = 0; s1 = 0.0;
for (i = 0; i < vs->nhosts; i++) { for (i = 0; i < vs->nhosts; i++) {
if (!vs->hosts[i].backend->healthy) if (!vs->hosts[i].backend->healthy)
continue; continue;
s2 += vs->hosts[i].weight; s1 += vs->hosts[i].weight;
if (r < s2) if (r >= s1)
break; continue;
} vbe = VBE_GetVbe(sp, vs->hosts[i].backend);
if (vbe != NULL)
if (s2 != s1) { return (vbe);
/* break;
* Health bit changed in an unusable way while we
* worked the problem. Usable changes are any that
* result in the same sum we prepared for.
*/
continue;
} }
vbe = VBE_GetVbe(sp, vs->hosts[i].backend);
if (vbe != NULL)
return (vbe);
k++; k++;
} }
return (NULL); return (NULL);
......
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