Commit ff3e6630 authored by Julian Wiesener's avatar Julian Wiesener

added backend_n

parent df36795d
...@@ -147,11 +147,24 @@ Initializes the hash ring. This function must be called after all backends are ...@@ -147,11 +147,24 @@ Initializes the hash ring. This function must be called after all backends are
added. The argument is the numbers of replicas the hash ring contains for each added. The argument is the numbers of replicas the hash ring contains for each
backend. backend.
INT .hash_string(STRING, ENUM { CRC32, SHA256, RS })
----------------------------------------------------
Returns the hash of its first argument using the hash
algorithm defined.
BACKEND .backend() BACKEND .backend()
------------------ ------------------
Returns a backend based on the default hash of the request URL. Returns a backend based on the default hash of the request URL.
BACKEND .backend_n(INT, BOOL, BOOL, INT)
----------------------------
Returns the n-th backend (first parameter) with respect of altsrv_p (second
parameter) and respect of its healthy state (third parameter) for the given
hash (last parameter).
BACKEND .backend_by_int(INT) BACKEND .backend_by_int(INT)
---------------------------- ----------------------------
...@@ -162,11 +175,14 @@ BACKEND .backend_by_string(STRING) ...@@ -162,11 +175,14 @@ BACKEND .backend_by_string(STRING)
---------------------------------- ----------------------------------
Returns a backend based on the default hash of its argument. Returns a backend based on the default hash of its argument.
DEPRECATED: use .backend_by_int(hash_string()) instead
BACKEND .backend_by_string_hash(STRING, ENUM { CRC32, SHA256, RS }) BACKEND .backend_by_string_hash(STRING, ENUM { CRC32, SHA256, RS })
------------------------------------------------------------------- -------------------------------------------------------------------
Returns a backend based on the hash of its first argument using the hash Returns a backend based on the hash of its first argument using the hash
algorithm defined. algorithm defined.
DEPRECATED: use .backend_by_int(hash_string()) instead
LIMITATIONS LIMITATIONS
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "cache/cache.h" #include "cache/cache.h"
...@@ -120,6 +121,21 @@ vmod_vslp_init_hashcircle(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslp ...@@ -120,6 +121,21 @@ vmod_vslp_init_hashcircle(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslp
vslpdir_init_hashcircle(vslpd->vslpd, replicas); vslpdir_init_hashcircle(vslpd->vslpd, replicas);
} }
VCL_INT __match_proto__(td_vslp_vslp_hash_string)
vmod_vslp_hash_string(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_STRING s, VCL_ENUM hash_m)
{
uint32_t hash;
hash_func hash_fp;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
hash_fp = vslp_get_hash_fp(hash_m);
hash = hash_fp(s ? s : "");
return (hash);
}
VCL_BACKEND __match_proto__(td_vslp_vslp_backend) VCL_BACKEND __match_proto__(td_vslp_vslp_backend)
vmod_vslp_backend(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd) vmod_vslp_backend(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd)
{ {
...@@ -139,7 +155,20 @@ vmod_vslp_backend(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd) ...@@ -139,7 +155,20 @@ vmod_vslp_backend(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd)
} }
hash = vslpd->vslpd->hash_fp(http->hd[HTTP_HDR_URL].b); hash = vslpd->vslpd->hash_fp(http->hd[HTTP_HDR_URL].b);
be = vslpdir_pick_be(vslpd->vslpd, ctx, hash); be = vslpdir_pick_be(vslpd->vslpd, ctx, hash, 0, true, true);
return (be);
}
VCL_BACKEND __match_proto__(td_vslp_vslp_backend_n)
vmod_vslp_backend_n(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd, VCL_INT n, VCL_BOOL altsrv_p, VCL_BOOL healthy, VCL_INT i)
{
VCL_BACKEND be;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
be = vslpdir_pick_be(vslpd->vslpd, ctx, i, n, altsrv_p, healthy);
return (be); return (be);
} }
...@@ -152,7 +181,7 @@ vmod_vslp_backend_by_int(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd ...@@ -152,7 +181,7 @@ vmod_vslp_backend_by_int(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vslpd
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC); CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
be = vslpdir_pick_be(vslpd->vslpd, ctx, i); be = vslpdir_pick_be(vslpd->vslpd, ctx, i, 0, true, true);
return (be); return (be);
} }
...@@ -167,7 +196,7 @@ vmod_vslp_backend_by_string(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vs ...@@ -167,7 +196,7 @@ vmod_vslp_backend_by_string(const struct vrt_ctx *ctx, struct vmod_vslp_vslp *vs
CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC); CHECK_OBJ_NOTNULL(vslpd, VMOD_VSLP_VSLP_MAGIC);
hash = vslpd->vslpd->hash_fp(s ? s : ""); hash = vslpd->vslpd->hash_fp(s ? s : "");
be = vslpdir_pick_be(vslpd->vslpd, ctx, hash); be = vslpdir_pick_be(vslpd->vslpd, ctx, hash, 0, true, true);
return (be); return (be);
} }
...@@ -184,7 +213,7 @@ vmod_vslp_backend_by_string_hash(const struct vrt_ctx *ctx, struct vmod_vslp_vsl ...@@ -184,7 +213,7 @@ vmod_vslp_backend_by_string_hash(const struct vrt_ctx *ctx, struct vmod_vslp_vsl
hash_fp = vslp_get_hash_fp(hash_m); hash_fp = vslp_get_hash_fp(hash_m);
hash = hash_fp(s ? s : ""); hash = hash_fp(s ? s : "");
be = vslpdir_pick_be(vslpd->vslpd, ctx, hash); be = vslpdir_pick_be(vslpd->vslpd, ctx, hash, 0, true, true);
return (be); return (be);
} }
...@@ -34,7 +34,9 @@ $Method VOID .set_rampup_ratio(REAL) ...@@ -34,7 +34,9 @@ $Method VOID .set_rampup_ratio(REAL)
$Method VOID .set_rampup_time(DURATION) $Method VOID .set_rampup_time(DURATION)
$Method VOID .set_hash(ENUM { CRC32, SHA256, RS }) $Method VOID .set_hash(ENUM { CRC32, SHA256, RS })
$Method VOID .init_hashcircle(INT) $Method VOID .init_hashcircle(INT)
$Method INT .hash_string(STRING, ENUM { CRC32, SHA256, RS })
$Method BACKEND .backend() $Method BACKEND .backend()
$Method BACKEND .backend_n(INT, BOOL, BOOL, INT)
$Method BACKEND .backend_by_int(INT) $Method BACKEND .backend_by_int(INT)
$Method BACKEND .backend_by_string(STRING) $Method BACKEND .backend_by_string(STRING)
$Method BACKEND .backend_by_string_hash(STRING, ENUM { CRC32, SHA256, RS }) $Method BACKEND .backend_by_string_hash(STRING, ENUM { CRC32, SHA256, RS })
...@@ -378,24 +378,31 @@ vslpdir_any_healthy(struct vslpdir *vslpd) ...@@ -378,24 +378,31 @@ vslpdir_any_healthy(struct vslpdir *vslpd)
return (retval); return (retval);
} }
VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, uint32_t hash) VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, uint32_t hash,
VCL_INT n_retry, VCL_BOOL altsrv_p, VCL_BOOL healthy)
{ {
VCL_BACKEND be; VCL_BACKEND be;
int chosen, be_choice, restarts_o, restarts, n_retry = 0; int chosen, be_choice, restarts_o = 0, restarts = 0;
struct vslp_state state; struct vslp_state state;
CHECK_OBJ_NOTNULL(vslpd, VSLPDIR_MAGIC); CHECK_OBJ_NOTNULL(vslpd, VSLPDIR_MAGIC);
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(ctx->vsl); AN(ctx->vsl);
if(altsrv_p)
be_choice = (scalbn(random(), -31) > vslpd->altsrv_p); be_choice = (scalbn(random(), -31) > vslpd->altsrv_p);
if(n_retry == 0) {
if (ctx->bo) { if (ctx->bo) {
restarts = restarts_o = ctx->bo->retries; restarts = restarts_o = ctx->bo->retries;
} else { } else {
AN(ctx->req); AN(ctx->req);
restarts = restarts_o = ctx->req->restarts; restarts = restarts_o = ctx->req->restarts;
} }
} else {
n_retry--;
}
state.picklist = 0; state.picklist = 0;
state.vslpd = vslpd; state.vslpd = vslpd;
...@@ -421,7 +428,10 @@ VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, ui ...@@ -421,7 +428,10 @@ VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, ui
{ {
n_retry++; n_retry++;
if(healthy)
chosen = vslp_choose_next_healthy(&state, n_retry); chosen = vslp_choose_next_healthy(&state, n_retry);
else
chosen = vslp_choose_next(&state, n_retry);
if(chosen < 0) { if(chosen < 0) {
VSLb(ctx->vsl, SLT_Debug, VSLb(ctx->vsl, SLT_Debug,
...@@ -444,12 +454,17 @@ VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, ui ...@@ -444,12 +454,17 @@ VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, ui
return NULL; return NULL;
} }
if (! healthy) {
AN(be);
return (be);
}
if (be->healthy(be, NULL)) if (be->healthy(be, NULL))
{ {
if(!vslp_be_healthy(&state, chosen)) if(!vslp_be_healthy(&state, chosen))
be_choice ^= be_choice; be_choice ^= be_choice;
if(!be_choice) if(altsrv_p && !be_choice)
{ {
chosen = vslp_choose_next_healthy(&state, n_retry); chosen = vslp_choose_next_healthy(&state, n_retry);
if(chosen < 0) { if(chosen < 0) {
......
...@@ -72,4 +72,5 @@ void vslpdir_lock(struct vslpdir *vslpd); ...@@ -72,4 +72,5 @@ void vslpdir_lock(struct vslpdir *vslpd);
void vslpdir_unlock(struct vslpdir *vslpd); void vslpdir_unlock(struct vslpdir *vslpd);
void vslpdir_expand(struct vslpdir *vslpd, unsigned n); void vslpdir_expand(struct vslpdir *vslpd, unsigned n);
unsigned vslpdir_any_healthy(struct vslpdir *vslpd); unsigned vslpdir_any_healthy(struct vslpdir *vslpd);
VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, uint32_t hash); VCL_BACKEND vslpdir_pick_be(struct vslpdir *vslpd, const struct vrt_ctx *ctx, uint32_t hash,
VCL_INT n_retry, VCL_BOOL altsrv_p, VCL_BOOL healthy);
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