unsigned vdir_any_healthy(struct vdir *vd, const struct busyobj *bo, double *changed) { unsigned retval = 0; VCL_BACKEND be; unsigned u; double c; CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); vdir_lock(vd); if (changed != NULL) *changed = 0; for (u = 0; u < vd->n_backend; u++) { be = vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); retval = be->healthy(be, bo, &c); if (changed != NULL && c > *changed) *changed = c; if (retval) break; } vdir_unlock(vd); return (retval); }
VCL_BACKEND vdir_pick_be(struct vdir *vd, const struct busyobj *bo, double w, unsigned nloops) { struct vbitmap *vbm = NULL; unsigned u, v, l; VCL_BACKEND be = NULL; double tw; int nbe; tw = vd->total_weight; nbe = vd->n_backend; assert(w >= 0.0 && w <= 1.0); vdir_lock(vd); for (l = 0; nbe > 0 && tw > 0.0 && l <nloops; l++) { u = vdir_pick_by_weight(vd, w * tw, vbm); be = vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); if (be->healthy(be, bo->digest)) break; if (l == 0) { vbm = vd->vbm; for (v = 0; v < nbe; v++) vbit_clr(vbm, v); } vbit_set(vbm, u); nbe--; tw -= vd->weight[u]; be = NULL; } vdir_unlock(vd); return (be); }
unsigned vdir_any_healthy(struct vdir *vd, const uint8_t *digest) { unsigned retval = 0; VCL_BACKEND be; unsigned u; CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); vdir_lock(vd); for (u = 0; u < vd->n_backend; u++) { be = vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); if (be->healthy(be, digest)) { retval = 1; break; } } vdir_unlock(vd); return (retval); }
static int shard_next(struct shard_state *state, VCL_INT skip, VCL_BOOL healthy) { int c, chosen = -1; uint32_t ringsz; VCL_BACKEND be; double changed; struct shard_be_info *sbe; AN(state); assert(state->idx >= 0); CHECK_OBJ_NOTNULL(state->shardd, SHARDDIR_MAGIC); if (state->pickcount >= state->shardd->n_backend) return -1; ringsz = state->shardd->n_backend * state->shardd->replicas; while (state->pickcount < state->shardd->n_backend && skip >= 0) { c = state->shardd->hashcircle[state->idx].host; if (! vbit_test(state->picklist, c)) { vbit_set(state->picklist, c); state->pickcount++; sbe = NULL; be = state->shardd->backend[c].backend; AN(be); if (be->healthy(be, state->ctx->bo, &changed)) { if (skip-- == 0) { chosen = c; sbe = &state->last; } else { sbe = &state->previous; } } else if (!healthy && skip-- == 0) { chosen = c; sbe = &state->last; } if (sbe == &state->last && state->last.hostid != -1) memcpy(&state->previous, &state->last, sizeof(state->previous)); if (sbe) { sbe->hostid = c; sbe->healthy = 1; sbe->changed = changed; } if (chosen != -1) break; } if (++(state->idx) == ringsz) state->idx = 0; } return chosen; }