static proxy_worker *find_best_byrequests(proxy_balancer *balancer, request_rec *r) { int i; int total_factor = 0; proxy_worker *worker; proxy_worker *mycandidate = NULL; int cur_lbset = 0; int max_lbset = 0; int checking_standby; int checked_standby; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: Entering byrequests for BALANCER (%s)", balancer->name); /* First try to see if we have available candidate */ do { checking_standby = checked_standby = 0; while (!mycandidate && !checked_standby) { worker = (proxy_worker *)balancer->workers->elts; for (i = 0; i < balancer->workers->nelts; i++, worker++) { if (!checking_standby) { /* first time through */ if (worker->s->lbset > max_lbset) max_lbset = worker->s->lbset; } if (worker->s->lbset > cur_lbset) continue; if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) ) continue; /* If the worker is in error state run * retry on that worker. It will be marked as * operational if the retry timeout is elapsed. * The worker might still be unusable, but we try * anyway. */ if (!PROXY_WORKER_IS_USABLE(worker)) ap_proxy_retry_worker("BALANCER", worker, r->server); /* Take into calculation only the workers that are * not in error state or not disabled. */ if (PROXY_WORKER_IS_USABLE(worker)) { worker->s->lbstatus += worker->s->lbfactor; total_factor += worker->s->lbfactor; if (!mycandidate || worker->s->lbstatus > mycandidate->s->lbstatus) mycandidate = worker; } } checked_standby = checking_standby++; } cur_lbset++; } while (cur_lbset <= max_lbset && !mycandidate); if (mycandidate) { mycandidate->s->lbstatus -= total_factor; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: byrequests selected worker \"%s\" : busy %" APR_SIZE_T_FMT " : lbstatus %d", mycandidate->name, mycandidate->s->busy, mycandidate->s->lbstatus); } return mycandidate; }
static proxy_worker *find_best_roundrobin(proxy_balancer *balancer, request_rec *r) { int i; proxy_worker **worker; proxy_worker *mycandidate = NULL; int checking_standby; int checked_standby; rr_data *ctx; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01116) "proxy: Entering roundrobin for BALANCER %s (%d)", balancer->s->name, (int)getpid()); /* Example creating a file and writing using APR framework */ apr_pool_t *tpool; apr_pool_create(&tpool, r->pool); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(05001) "Before Checking Bloom"); const char *packetp = ap_server_root_relative(tpool, "bloom/packet.txt"); const char *filterp = ap_server_root_relative(tpool, "bloom/filter.txt"); const char *debug = ap_server_root_relative(tpool, "bloom/debug.log"); FILE * debugp = fopen(debug, "w+"); int check = checkLastFromFiles(r, filterp, packetp); fprintf(debugp, "CHECK: %d\n", check); fflush(debugp); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ const apr_array_header_t *fields; apr_table_entry_t *e = 0; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ fields = apr_table_elts(r->headers_in); e = (apr_table_entry_t *) fields->elts; for(i = 0; i < fields->nelts; i++) { ap_rprintf(r, "<b>%s</b>: %s<br/>", e[i].key, e[i].val); } fclose(debugp); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(05002) "After Checking Bloom"); /* The index of the candidate last chosen is stored in ctx->index */ if (!balancer->context) { /* UGLY */ ctx = apr_pcalloc(r->server->process->pconf, sizeof(rr_data)); balancer->context = (void *)ctx; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01117) "proxy: Creating roundrobin ctx for BALANCER %s (%d)", balancer->s->name, (int)getpid()); } else { ctx = (rr_data *)balancer->context; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01118) "proxy: roundrobin index: %d (%d)", ctx->index, (int)getpid()); checking_standby = checked_standby = 0; while (!mycandidate && !checked_standby) { worker = (proxy_worker **)balancer->workers->elts; for (i = 0; i < balancer->workers->nelts; i++, worker++) { if (i < ctx->index) continue; if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(*worker) : PROXY_WORKER_IS_STANDBY(*worker)) || (PROXY_WORKER_IS_DRAINING(*worker)) ) { continue; } // if (!PROXY_WORKER_IS_USABLE(*worker)) // ap_proxy_retry_worker("BALANCER", *worker, r->server); if (PROXY_WORKER_IS_USABLE(*worker)) { mycandidate = *worker; break; } } checked_standby = checking_standby++; } ctx->index += 1; if (ctx->index >= balancer->workers->nelts) { ctx->index = 0; } return mycandidate; }
/* Find the worker that has the 'route' defined */ static proxy_worker *find_route_worker(proxy_balancer *balancer, const char *route, request_rec *r) { int i; int checking_standby; int checked_standby; proxy_worker *worker; checking_standby = checked_standby = 0; while (!checked_standby) { worker = (proxy_worker *)balancer->workers->elts; for (i = 0; i < balancer->workers->nelts; i++, worker++) { if ( (checking_standby ? !PROXY_WORKER_IS_STANDBY(worker) : PROXY_WORKER_IS_STANDBY(worker)) ) continue; if (*(worker->s->route) && strcmp(worker->s->route, route) == 0) { if (worker && PROXY_WORKER_IS_USABLE(worker)) { return worker; } else { /* * If the worker is in error state run * retry on that worker. It will be marked as * operational if the retry timeout is elapsed. * The worker might still be unusable, but we try * anyway. */ ap_proxy_retry_worker("BALANCER", worker, r->server); if (PROXY_WORKER_IS_USABLE(worker)) { return worker; } else { /* * We have a worker that is unusable. * It can be in error or disabled, but in case * it has a redirection set use that redirection worker. * This enables to safely remove the member from the * balancer. Of course you will need some kind of * session replication between those two remote. */ if (*worker->s->redirect) { proxy_worker *rworker = NULL; rworker = find_route_worker(balancer, worker->s->redirect, r); /* Check if the redirect worker is usable */ if (rworker && !PROXY_WORKER_IS_USABLE(rworker)) { /* * If the worker is in error state run * retry on that worker. It will be marked as * operational if the retry timeout is elapsed. * The worker might still be unusable, but we try * anyway. */ ap_proxy_retry_worker("BALANCER", rworker, r->server); } if (rworker && PROXY_WORKER_IS_USABLE(rworker)) return rworker; } } } } } checked_standby = checking_standby++; } return NULL; }