Browse Source

Properly handle userproxy priorities

master
Con Kolivas 8 years ago
parent
commit
cc6e431b13
  1. 55
      src/stratifier.c

55
src/stratifier.c

@ -2081,19 +2081,25 @@ static int64_t prio_sort(proxy_t *a, proxy_t *b)
return (a->priority - b->priority); return (a->priority - b->priority);
} }
/* Masked increment */
static int64_t masked_inc(int64_t value, int64_t mask)
{
value &= ~mask;
value++;
value |= mask;
return value;
}
/* Priority values can be sparse, they do not need to be sequential */ /* Priority values can be sparse, they do not need to be sequential */
static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority) static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority)
{ {
proxy_t *tmpa, *tmpb, *exists = NULL; proxy_t *tmpa, *tmpb, *exists = NULL;
int64_t next_prio = 0; int64_t mask, next_prio = 0;
/* Encode the userid as the high bits in priority */ /* Encode the userid as the high bits in priority */
if (!proxy->global) { mask = proxy->userid;
int64_t high_bits = proxy->userid; mask <<= 32;
priority |= mask;
high_bits <<= 32;
priority |= high_bits;
}
/* See if the priority is already in use */ /* See if the priority is already in use */
HASH_ITER(hh, sdata->proxies, tmpa, tmpb) { HASH_ITER(hh, sdata->proxies, tmpa, tmpb) {
@ -2101,7 +2107,7 @@ static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority)
break; break;
if (tmpa->priority == priority) { if (tmpa->priority == priority) {
exists = tmpa; exists = tmpa;
next_prio = exists->priority + 1; next_prio = masked_inc(priority, mask);
break; break;
} }
} }
@ -2109,7 +2115,7 @@ static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority)
HASH_ITER(hh, exists, tmpa, tmpb) { HASH_ITER(hh, exists, tmpa, tmpb) {
if (tmpa->priority > next_prio) if (tmpa->priority > next_prio)
break; break;
tmpa->priority++; tmpa->priority = masked_inc(tmpa->priority, mask);
next_prio++; next_prio++;
} }
proxy->priority = priority; proxy->priority = priority;
@ -2225,11 +2231,15 @@ static proxy_t *existing_subproxy(sdata_t *sdata, const int id, const int subid)
return subproxy; return subproxy;
} }
static void check_userproxies(sdata_t *sdata, proxy_t *proxy, const int userid);
static void set_proxy_prio(sdata_t *sdata, proxy_t *proxy, const int priority) static void set_proxy_prio(sdata_t *sdata, proxy_t *proxy, const int priority)
{ {
mutex_lock(&sdata->proxy_lock); mutex_lock(&sdata->proxy_lock);
__set_proxy_prio(sdata, proxy, priority); __set_proxy_prio(sdata, proxy, priority);
mutex_unlock(&sdata->proxy_lock); mutex_unlock(&sdata->proxy_lock);
check_userproxies(sdata, proxy, proxy->userid);
} }
/* Set proxy to the current proxy and calculate how much headroom it has */ /* Set proxy to the current proxy and calculate how much headroom it has */
@ -2544,7 +2554,7 @@ static void recruit_best_userproxy(sdata_t *sdata, const int userid, const int r
/* Check how much headroom the userid proxies have and reconnect any clients /* Check how much headroom the userid proxies have and reconnect any clients
* that are not bound to it that should be */ * that are not bound to it that should be */
static void check_userproxies(sdata_t *sdata, const int userid) static void check_userproxies(sdata_t *sdata, proxy_t *proxy, const int userid)
{ {
int64_t headroom = proxy_headroom(sdata, userid); int64_t headroom = proxy_headroom(sdata, userid);
stratum_instance_t *client, *tmpclient; stratum_instance_t *client, *tmpclient;
@ -2558,8 +2568,10 @@ static void check_userproxies(sdata_t *sdata, const int userid)
continue; continue;
if (client->user_id != userid) if (client->user_id != userid)
continue; continue;
/* Is this client bound to a dead proxy? */ /* Is the client already bound to a proxy of its own userid of
if (!client->reconnect && client->proxy->userid == userid) * a higher priority than this one. */
if (client->proxy->userid == userid &&
client->proxy->parent->priority <= proxy->parent->priority)
continue; continue;
if (headroom-- < 1) if (headroom-- < 1)
continue; continue;
@ -2681,7 +2693,7 @@ static void update_notify(ckpool_t *ckp, const char *cmd)
if (proxy->parent != best_proxy(sdata)->parent) if (proxy->parent != best_proxy(sdata)->parent)
reconnect_clients(sdata); reconnect_clients(sdata);
} else } else
check_userproxies(sdata, proxy->userid); check_userproxies(sdata, proxy, proxy->userid);
clean |= new_block; clean |= new_block;
LOGINFO("Proxy %d:%d broadcast updated stratum notify with%s clean", id, LOGINFO("Proxy %d:%d broadcast updated stratum notify with%s clean", id,
subid, clean ? "" : "out"); subid, clean ? "" : "out");
@ -4355,19 +4367,16 @@ static proxy_t *__best_subproxy(proxy_t *proxy)
* running out of room. */ * running out of room. */
static sdata_t *select_sdata(const ckpool_t *ckp, sdata_t *ckp_sdata, const int userid) static sdata_t *select_sdata(const ckpool_t *ckp, sdata_t *ckp_sdata, const int userid)
{ {
proxy_t *current, *proxy, *tmp, *best = NULL; proxy_t *global, *proxy, *tmp, *best = NULL;
if (!ckp->proxy || ckp->passthrough) if (!ckp->proxy || ckp->passthrough)
return ckp_sdata; return ckp_sdata;
current = ckp_sdata->proxy;
if (!current) {
LOGWARNING("No proxy available yet to generate subscribes");
return NULL;
}
/* Proxies are ordered by priority so first available will be the best /* Proxies are ordered by priority so first available will be the best
* priority */ * priority */
mutex_lock(&ckp_sdata->proxy_lock); mutex_lock(&ckp_sdata->proxy_lock);
best = global = ckp_sdata->proxy;
HASH_ITER(hh, ckp_sdata->proxies, proxy, tmp) { HASH_ITER(hh, ckp_sdata->proxies, proxy, tmp) {
if (proxy->userid < userid) if (proxy->userid < userid)
continue; continue;
@ -4381,12 +4390,14 @@ static sdata_t *select_sdata(const ckpool_t *ckp, sdata_t *ckp_sdata, const int
if (!best) { if (!best) {
if (!userid) if (!userid)
LOGWARNING("Temporarily insufficient subproxies to accept more clients"); LOGWARNING("Temporarily insufficient proxies to accept more clients");
else
LOGNOTICE("Temporarily insufficient proxies for userid %d to accept more clients", userid);
return NULL; return NULL;
} }
if (!userid) { if (!userid) {
if (best->id != current->id || current_headroom(ckp_sdata, &proxy) < 2) if (best->id != global->id || current_headroom(ckp_sdata, &proxy) < 2)
generator_recruit(ckp, current->id, 1); generator_recruit(ckp, global->id, 1);
} else { } else {
if (proxy_headroom(ckp_sdata, userid) < 2) if (proxy_headroom(ckp_sdata, userid) < 2)
generator_recruit(ckp, best->id, 1); generator_recruit(ckp, best->id, 1);

Loading…
Cancel
Save