vbe_dir_healthy(const struct director *d, const struct busyobj *bo, double *changed) { struct backend *be; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC); return (VBE_Healthy(be, changed)); }
vdi_simple_healthy(const struct director *d, double *changed) { struct vdi_simple *vs; struct backend *be; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); be = vs->backend; CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC); return (VBE_Healthy(be, changed)); }
static unsigned vdi_round_robin_healthy(double now, const struct director *d, uintptr_t target) { 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 (VBE_Healthy(now, backend, target)) return 1; } return 0; }
static struct vbc * vbe_GetVbe(struct busyobj *bo, struct vdi_simple *vs) { struct vbc *vc; struct backend *bp; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC); bp = vs->backend; CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); /* first look for vbc's we can recycle */ while (1) { Lck_Lock(&bp->mtx); vc = VTAILQ_FIRST(&bp->connlist); if (vc != NULL) { bp->refcount++; assert(vc->backend == bp); assert(vc->fd >= 0); AN(vc->addr); VTAILQ_REMOVE(&bp->connlist, vc, list); } Lck_Unlock(&bp->mtx); if (vc == NULL) break; if (vbe_CheckFd(vc->fd)) { /* XXX locking of stats */ VSC_C_main->backend_reuse += 1; VSLb(bo->vsl, SLT_Backend, "%d %s %s", vc->fd, bo->director->vcl_name, bp->display_name); vc->vdis = vs; vc->recycled = 1; return (vc); } VSC_C_main->backend_toolate++; VSLb(bo->vsl, SLT_BackendClose, "%d %s toolate", vc->fd, bp->display_name); /* Checkpoint log to flush all info related to this connection before the OS reuses the FD */ VSL_Flush(bo->vsl, 0); VTCP_close(&vc->fd); VBE_DropRefConn(bp); vc->backend = NULL; VBE_ReleaseConn(vc); } if (!VBE_Healthy(bp, NULL)) { VSC_C_main->backend_unhealthy++; return (NULL); } if (vs->vrt->max_connections > 0 && bp->n_conn >= vs->vrt->max_connections) { VSC_C_main->backend_busy++; return (NULL); } vc = vbe_NewConn(); assert(vc->fd == -1); AZ(vc->backend); bes_conn_try(bo, vc, vs); if (vc->fd < 0) { VBE_ReleaseConn(vc); VSC_C_main->backend_fail++; return (NULL); } vc->backend = bp; VSC_C_main->backend_conn++; VSLb(bo->vsl, SLT_Backend, "%d %s %s", vc->fd, bo->director->vcl_name, bp->display_name); vc->vdis = vs; return (vc); }
static struct vbc * vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo) { struct vbc *vc; double tmod; char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE]; char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE]; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); AN(bp->vsc); if (!VBE_Healthy(bp, NULL)) { // XXX: per backend stats ? VSC_C_main->backend_unhealthy++; return (NULL); } if (bp->max_connections > 0 && bp->n_conn >= bp->max_connections) { // XXX: per backend stats ? VSC_C_main->backend_busy++; return (NULL); } AZ(bo->htc); bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc); if (bo->htc == NULL) /* XXX: counter ? */ return (NULL); bo->htc->doclose = SC_NULL; FIND_TMO(connect_timeout, tmod, bo, bp); vc = VBT_Get(bp->tcp_pool, tmod, bp, wrk); if (vc == NULL) { // XXX: Per backend stats ? VSC_C_main->backend_fail++; bo->htc = NULL; return (NULL); } assert(vc->fd >= 0); AN(vc->addr); Lck_Lock(&bp->mtx); bp->n_conn++; bp->vsc->conn++; bp->vsc->req++; Lck_Unlock(&bp->mtx); if (bp->proxy_header != 0) VPX_Send_Proxy(vc->fd, bp->proxy_header, bo->sp); VTCP_myname(vc->fd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); VTCP_hisname(vc->fd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); VSLb(bo->vsl, SLT_BackendOpen, "%d %s %s %s %s %s", vc->fd, bp->display_name, abuf2, pbuf2, abuf1, pbuf1); INIT_OBJ(bo->htc, HTTP_CONN_MAGIC); bo->htc->priv = vc; bo->htc->fd = vc->fd; FIND_TMO(first_byte_timeout, bo->htc->first_byte_timeout, bo, bp); FIND_TMO(between_bytes_timeout, bo->htc->between_bytes_timeout, bo, bp); return (vc); }