Browse Source

Store dead proxy instances to be recycled if possible

master
Con Kolivas 10 years ago
parent
commit
3d44a13470
  1. 53
      src/generator.c

53
src/generator.c

@ -78,6 +78,7 @@ typedef struct proxy_instance proxy_instance_t;
struct proxy_instance { struct proxy_instance {
UT_hash_handle hh; UT_hash_handle hh;
proxy_instance_t *next; /* For dead proxy list */ proxy_instance_t *next; /* For dead proxy list */
proxy_instance_t *prev; /* For dead proxy list */
ckpool_t *ckp; ckpool_t *ckp;
connsock_t *cs; connsock_t *cs;
@ -899,8 +900,8 @@ static bool send_pong(proxy_instance_t *proxi, json_t *val)
} }
static void prepare_proxy(proxy_instance_t *proxi); static void prepare_proxy(proxy_instance_t *proxi);
static proxy_instance_t *create_subproxy(proxy_instance_t *proxi); static proxy_instance_t *create_subproxy(gdata_t *gdata, proxy_instance_t *proxi);
static bool recruit_subproxy(proxy_instance_t *proxi); static bool recruit_subproxy(gdata_t *gdata, proxy_instance_t *proxi);
static void add_subproxy(proxy_instance_t *proxi, proxy_instance_t *subproxy) static void add_subproxy(proxy_instance_t *proxi, proxy_instance_t *subproxy)
{ {
@ -919,22 +920,32 @@ static proxy_instance_t *__subproxy_by_id(proxy_instance_t *proxy, const int id)
return subproxy; return subproxy;
} }
/* Remove the subproxy from the proxi list. Do not remove its ram in case of /* Add to the dead list to be recycled if possible */
* dangling references */ static void store_proxy(gdata_t *gdata, proxy_instance_t *proxy)
{
mutex_lock(&gdata->lock);
DL_APPEND(gdata->dead_proxies, proxy);
mutex_unlock(&gdata->lock);
}
/* Remove the subproxy from the proxi list and put it on the dead list */
static void disable_subproxy(gdata_t *gdata, proxy_instance_t *proxi, proxy_instance_t *subproxy) static void disable_subproxy(gdata_t *gdata, proxy_instance_t *proxi, proxy_instance_t *subproxy)
{ {
mutex_lock(&proxi->proxy_lock); mutex_lock(&proxi->proxy_lock);
subproxy->disabled = true; subproxy->disabled = true;
/* Make sure subproxy is still in the list */ /* Make sure subproxy is still in the list */
if (__subproxy_by_id(proxi, subproxy->id)) { subproxy = __subproxy_by_id(proxi, subproxy->id);
if (subproxy) {
HASH_DEL(proxi->subproxies, subproxy); HASH_DEL(proxi->subproxies, subproxy);
proxi->client_headroom -= proxi->clients_per_proxy; proxi->client_headroom -= proxi->clients_per_proxy;
LL_PREPEND(gdata->dead_proxies, subproxy);
} }
mutex_unlock(&proxi->proxy_lock); mutex_unlock(&proxi->proxy_lock);
if (subproxy)
store_proxy(gdata, subproxy);
if (proxi->client_headroom < 42 && proxi->alive) if (proxi->client_headroom < 42 && proxi->alive)
recruit_subproxy(proxi); recruit_subproxy(gdata, proxi);
} }
static bool parse_reconnect(proxy_instance_t *proxi, json_t *val) static bool parse_reconnect(proxy_instance_t *proxi, json_t *val)
@ -988,7 +999,7 @@ static bool parse_reconnect(proxy_instance_t *proxi, json_t *val)
ret = true; ret = true;
/* If this isn't a parent proxy, add a new subproxy to the parent */ /* If this isn't a parent proxy, add a new subproxy to the parent */
if (proxi != proxi->proxy) { if (proxi != proxi->proxy) {
newproxi = create_subproxy(proxi); newproxi = create_subproxy(gdata, proxi);
add_subproxy(proxi, newproxi); add_subproxy(proxi, newproxi);
goto out; goto out;
} }
@ -1508,6 +1519,7 @@ static void passthrough_add_send(proxy_instance_t *proxi, const char *msg)
static bool proxy_alive(ckpool_t *ckp, server_instance_t *si, proxy_instance_t *proxi, static bool proxy_alive(ckpool_t *ckp, server_instance_t *si, proxy_instance_t *proxi,
connsock_t *cs, bool pinging, int epfd) connsock_t *cs, bool pinging, int epfd)
{ {
gdata_t *gdata = ckp->data;
struct epoll_event event; struct epoll_event event;
bool ret = false; bool ret = false;
@ -1571,7 +1583,7 @@ out:
* recruit extra when asked by the stratifier. */ * recruit extra when asked by the stratifier. */
while (proxi->client_headroom < 42) { while (proxi->client_headroom < 42) {
/* Note recursive call of proxy_alive here */ /* Note recursive call of proxy_alive here */
if (!recruit_subproxy(proxi)) { if (!recruit_subproxy(gdata, proxi)) {
LOGWARNING("Unable to recruit extra subproxies after just %"PRId64, LOGWARNING("Unable to recruit extra subproxies after just %"PRId64,
proxi->client_headroom); proxi->client_headroom);
break; break;
@ -1587,11 +1599,21 @@ out:
/* Creates a duplicate instance or proxi to be used as a subproxy, ignoring /* Creates a duplicate instance or proxi to be used as a subproxy, ignoring
* fields we don't use in the subproxy. */ * fields we don't use in the subproxy. */
static proxy_instance_t *create_subproxy(proxy_instance_t *proxi) static proxy_instance_t *create_subproxy(gdata_t *gdata, proxy_instance_t *proxi)
{ {
proxy_instance_t *subproxy = ckzalloc(sizeof(proxy_instance_t)); proxy_instance_t *subproxy;
mutex_lock(&gdata->lock);
if (gdata->dead_proxies) {
/* Recycle an old proxy instance if one exists */
subproxy = gdata->dead_proxies;
DL_DELETE(gdata->dead_proxies, subproxy);
} else {
subproxy = ckzalloc(sizeof(proxy_instance_t));
subproxy->cs = ckzalloc(sizeof(connsock_t)); subproxy->cs = ckzalloc(sizeof(connsock_t));
}
mutex_unlock(&gdata->lock);
subproxy->cs->ckp = subproxy->ckp = proxi->ckp; subproxy->cs->ckp = subproxy->ckp = proxi->ckp;
subproxy->si = proxi->si; subproxy->si = proxi->si;
subproxy->id = proxi->subproxy_count; subproxy->id = proxi->subproxy_count;
@ -1603,15 +1625,14 @@ static proxy_instance_t *create_subproxy(proxy_instance_t *proxi)
return subproxy; return subproxy;
} }
static bool recruit_subproxy(proxy_instance_t *proxi) static bool recruit_subproxy(gdata_t *gdata, proxy_instance_t *proxi)
{ {
proxy_instance_t *subproxy = create_subproxy(proxi); proxy_instance_t *subproxy = create_subproxy(gdata, proxi);
int epfd = proxi->epfd; int epfd = proxi->epfd;
if (!proxy_alive(subproxy->ckp, subproxy->si, subproxy, subproxy->cs, false, epfd)) { if (!proxy_alive(subproxy->ckp, subproxy->si, subproxy, subproxy->cs, false, epfd)) {
LOGNOTICE("Subproxy failed proxy_alive testing"); LOGNOTICE("Subproxy failed proxy_alive testing");
free(subproxy->cs); store_proxy(gdata, subproxy);
free(subproxy);
return false; return false;
} }
@ -1943,7 +1964,7 @@ retry:
LOGDEBUG("Proxy received ping request"); LOGDEBUG("Proxy received ping request");
send_unix_msg(sockd, "pong"); send_unix_msg(sockd, "pong");
} else if (cmdmatch(buf, "recruit")) { } else if (cmdmatch(buf, "recruit")) {
recruit_subproxy(proxi); recruit_subproxy(gdata, proxi);
} else if (ckp->passthrough) { } else if (ckp->passthrough) {
/* Anything remaining should be stratum messages */ /* Anything remaining should be stratum messages */
passthrough_add_send(proxi, buf); passthrough_add_send(proxi, buf);

Loading…
Cancel
Save