diff --git a/include/lighttpd/virtualrequest.h b/include/lighttpd/virtualrequest.h index 12d23b0..01dd23a 100644 --- a/include/lighttpd/virtualrequest.h +++ b/include/lighttpd/virtualrequest.h @@ -95,6 +95,10 @@ LI_API void vrequest_reset(vrequest *vr); LI_API void vrequest_error(vrequest *vr); +LI_API void vrequest_backend_overloaded(vrequest *vr); +LI_API void vrequest_backend_dead(vrequest *vr); +LI_API void vrequest_backend_error(vrequest *vr, backend_error berror); + /* received all request headers */ LI_API void vrequest_handle_request_headers(vrequest *vr); /* received (partial) request content */ diff --git a/src/actions.c b/src/actions.c index b2acd5e..b12d16e 100644 --- a/src/actions.c +++ b/src/actions.c @@ -192,14 +192,16 @@ handler_t action_execute(vrequest *vr) { while (NULL != (ase = action_stack_top(as))) { if (as->backend_failed) { - while (ase->act->type != ACTION_TBALANCER || !ase->act->data.balancer.provide_backlog) { + /* pop top action in every case (if the balancer itself failed we don't want to restart it) */ + action_stack_pop(srv, vr, as); + while (NULL != (ase = action_stack_top(as)) && (ase->act->type != ACTION_TBALANCER || !ase->act->data.balancer.provide_backlog)) { action_stack_pop(srv, vr, as); ase = action_stack_top(as); - if (!ase) { /* no backlogging balancer found */ - if (vrequest_handle_direct(vr)) - vr->response.http_status = 503; - return HANDLER_GO_ON; - } + } + if (!ase) { /* no backlogging balancer found */ + if (vrequest_handle_direct(vr)) + vr->response.http_status = 503; + return HANDLER_GO_ON; } as->backend_failed = FALSE; @@ -216,12 +218,6 @@ handler_t action_execute(vrequest *vr) { case HANDLER_WAIT_FOR_FD: return res; } - if (as->backend_failed) { /* if balancer failed, pop it */ - action_stack_element *tmp_ase; - while (ase != (tmp_ase = action_stack_top(as))) { - action_stack_pop(srv, vr, as); - } - } continue; } if (ase->finished) { diff --git a/src/modules/mod_balancer.c b/src/modules/mod_balancer.c index 4273255..d5d2863 100644 --- a/src/modules/mod_balancer.c +++ b/src/modules/mod_balancer.c @@ -94,7 +94,7 @@ static handler_t balancer_act_select(vrequest *vr, gboolean backlog_provided, gp static handler_t balancer_act_fallback(vrequest *vr, gboolean backlog_provided, gpointer param, gpointer *context, backend_error error) { balancer *b = (balancer*) param; - gint be_ndx = GPOINTER_TO_INT(context); + gint be_ndx = GPOINTER_TO_INT(*context); backend *be = &g_array_index(b->backends, backend, be_ndx); UNUSED(backlog_provided); @@ -105,8 +105,8 @@ static handler_t balancer_act_fallback(vrequest *vr, gboolean backlog_provided, /* TODO implement fallback/backlog */ be->load--; - if (vrequest_handle_direct(vr)) - vr->response.http_status = 503; + *context = GINT_TO_POINTER(-1); + vrequest_backend_error(vr, error); return HANDLER_GO_ON; } diff --git a/src/virtualrequest.c b/src/virtualrequest.c index 2a695ba..8bacdfe 100644 --- a/src/virtualrequest.c +++ b/src/virtualrequest.c @@ -114,6 +114,21 @@ void vrequest_error(vrequest *vr) { vrequest_joblist_append(vr); } +void vrequest_backend_overloaded(vrequest *vr) { + vr->action_stack.backend_failed = TRUE; + vr->action_stack.backend_error = BACKEND_OVERLOAD; +} + +void vrequest_backend_error(vrequest *vr, backend_error berror) { + vr->action_stack.backend_failed = TRUE; + vr->action_stack.backend_error = berror; +} + +void vrequest_backend_dead(vrequest *vr) { + vr->action_stack.backend_failed = TRUE; + vr->action_stack.backend_error = BACKEND_DEAD; +} + /* received all request headers */ void vrequest_handle_request_headers(vrequest *vr) { if (VRS_CLEAN == vr->state) {