/* * Find the healthy backend corresponding to the weight r [0...1[ */ static struct vbc * vdi_random_pick_one(struct sess *sp, const struct vdi_random *vs, double r) { double w[vs->nhosts]; int i; double s1; assert(r >= 0.0 && r < 1.0); memset(w, 0, sizeof w); /* Sum up the weights of healty backends */ s1 = 0.0; for (i = 0; i < vs->nhosts; i++) { if (VDI_Healthy(vs->hosts[i].backend, sp)) w[i] = vs->hosts[i].weight; s1 += w[i]; } if (s1 == 0.0) return (NULL); r *= s1; s1 = 0.0; for (i = 0; i < vs->nhosts; i++) { s1 += w[i]; if (r < s1) return(VDI_GetFd(vs->hosts[i].backend, sp)); } return (NULL); }
static struct vbc * vdi_round_robin_getfd(const struct director *d, struct sess *sp) { int i; struct vdi_round_robin *vs; struct director *backend; struct vbc *vbe; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_ROUND_ROBIN_MAGIC); /* * In fallback mode we ignore the next_host and always grab the * first healthy backend we can find. */ for (i = 0; i < vs->nhosts; i++) { if (vs->mode == m_round_robin) { backend = vs->hosts[vs->next_host].backend; vs->next_host = (vs->next_host + 1) % vs->nhosts; } else /* m_fallback */ { backend = vs->hosts[i].backend; } if (!VDI_Healthy(backend, sp)) continue; vbe = VDI_GetFd(backend, sp); if (vbe != NULL) return (vbe); } return (NULL); }
vmod_healthy(const struct vrt_ctx *ctx, VCL_BACKEND be) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (be == NULL) return (0); CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); return (VDI_Healthy(be)); }
vmod_healthy(VRT_CTX, VCL_BACKEND be) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (be == NULL) return (0); CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); return (VDI_Healthy(be, ctx->bo)); }
unsigned VRT_r_bereq_backend_healthy(const struct vrt_ctx *ctx) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(ctx->bo->director, DIRECTOR_MAGIC); return (VDI_Healthy(ctx->bo->director, ctx->bo->digest)); }
unsigned VRT_r_req_backend_healthy(const struct vrt_ctx *ctx) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); /* * XXX: Not optimal, but we do not have a backend in vcl_deliver * XXX: and we have to return something. */ if (ctx->req->director == NULL) return (0); CHECK_OBJ_NOTNULL(ctx->req->director, DIRECTOR_MAGIC); return (VDI_Healthy(ctx->req->director, ctx->req->digest)); }
/* * Healthy if just a single backend is... */ static unsigned vdi_random_healthy(const struct director *d, const struct sess *sp) { struct vdi_random *vs; int i; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_RANDOM_MAGIC); for (i = 0; i < vs->nhosts; i++) { if (VDI_Healthy(vs->hosts[i].backend, sp)) return (1); } return (0); }
static unsigned vdi_round_robin_healthy(const struct director *d, const struct sess *sp) { struct vdi_round_robin *vs; struct director *backend; int i; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_ROUND_ROBIN_MAGIC); for (i = 0; i < vs->nhosts; i++) { backend = vs->hosts[i].backend; if (VDI_Healthy(backend, sp)) return (1); } return (0); }
static struct vbc * vdi_round_robin_getfd(const struct director *d, struct sess *sp) { int i; struct vdi_round_robin *vs; struct director *backend; struct vbc *vbe; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_ROUND_ROBIN_MAGIC); for (i = 0; i < vs->nhosts; i++) { backend = vs->hosts[vs->next_host].backend; vs->next_host = (vs->next_host + 1) % vs->nhosts; if (!VDI_Healthy(backend, sp)) continue; vbe = VDI_GetFd(backend, sp); if (vbe != NULL) return (vbe); } return (NULL); }