typedef struct vbe_conn *vdi_getfd_f(struct sess *sp);
typedef void vdi_fini_f(struct director *d);
+typedef unsigned vdi_healthy(const struct sess *sp);
struct director {
unsigned magic;
const char *name;
vdi_getfd_f *getfd;
vdi_fini_f *fini;
+ vdi_healthy *healthy;
void *priv;
};
return (NULL);
}
+static unsigned *
+vdi_random_healthy(const struct sess *sp)
+{
+ struct vdi_random *vs;
+ int i;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+ CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_RANDOM_MAGIC);
+
+ for (i = 0; i < vs->nhosts; i++) {
+ if (vs->hosts[i].backend->healthy)
+ return 1;
+ }
+ return 0;
+}
+
/*lint -e{818} not const-able */
static void
vdi_random_fini(struct director *d)
vs->dir.name = "random";
vs->dir.getfd = vdi_random_getfd;
vs->dir.fini = vdi_random_fini;
+ vs->dir.healthy = vdi_random_healthy;
vs->retries = t->retries;
if (vs->retries == 0)
return (NULL);
}
+static unsigned *
+vdi_round_robin_healthy(const struct sess *sp)
+{
+ struct vdi_round_robin *vs;
+ int i;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+ CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_ROUND_ROBIN_MAGIC);
+
+ for (i = 0; i < vs->nhosts; i++) {
+ if (vs->hosts[i].backend->healthy)
+ return 1;
+ }
+ return 0;
+}
+
/*lint -e{818} not const-able */
static void
vdi_round_robin_fini(struct director *d)
vs->dir.name = "round_robin";
vs->dir.getfd = vdi_round_robin_getfd;
vs->dir.fini = vdi_round_robin_fini;
+ vs->dir.healthy = vdi_round_robin_healthy;
vh = vs->hosts;
te = t->members;
return (VBE_GetVbe(sp, vs->backend));
}
+static unsigned *
+vdi_simple_healthy(const struct sess *sp)
+{
+ struct vdi_simple *vs;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+ CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_SIMPLE_MAGIC);
+ return vs->backend->healthy;
+}
+
/*lint -e{818} not const-able */
static void
vdi_simple_fini(struct director *d)
vs->dir.name = "simple";
vs->dir.getfd = vdi_simple_getfd;
vs->dir.fini = vdi_simple_fini;
+ vs->dir.healthy = vdi_simple_healthy;
vs->backend = VBE_AddBackend(cli, t->host);
#include "vrt_obj.h"
#include "vcl.h"
#include "cache.h"
-
+#include "cache_backend.h"
void *vrt_magic_string_end = &vrt_magic_string_end;
return (sp->obj->objhead->hash);
}
-int
-VRT_r_backend_health(const struct sess *sp)
+unsigned
+VRT_r_backend_healthy(const struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-#if 0
- CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
- return (sp->backend->health);
-#else
- INCOMPL();
- return (0);
-#endif
+ CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+ return (sp->director->healthy(sp));
}
/*--------------------------------------------------------------------*/
const char * VRT_r_resp_response(const struct sess *);
void VRT_l_resp_response(const struct sess *, const char *, ...);
double VRT_r_now(const struct sess *);
-int VRT_r_backend_health(const struct sess *);
+unsigned VRT_r_backend_healthy(const struct sess *);
vsb_cat(sb, "const char * VRT_r_resp_response(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_resp_response(const struct sess *, const char *, ...);\n");
vsb_cat(sb, "double VRT_r_now(const struct sess *);\n");
- vsb_cat(sb, "int VRT_r_backend_health(const struct sess *);\n");
+ vsb_cat(sb, "unsigned VRT_r_backend_healthy(const struct sess *);\n");
}
{recv pipe pass hash miss hit fetch deliver discard timeout}
"const struct sess *"
}
- { backend.health RO INT
+ { backend.healthy RO BOOL
{recv pipe pass hash miss hit fetch deliver discard timeout}
"const struct sess *"
}
#include "config.h"
#include <stdio.h>
-#include "config.h"
#include "vcc_compile.h"
struct var vcc_vars[] = {
0,
VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_DISCARD | VCL_MET_TIMEOUT
},
- { "backend.health", INT, 14,
- "VRT_r_backend_health(sp)",
+ { "backend.healthy", BOOL, 15,
+ "VRT_r_backend_healthy(sp)",
NULL,
V_RO,
0,