Browse Source

Move client culling and testing to the broadcast to avoid cycles of drop/test

master
Con Kolivas 10 years ago
parent
commit
2347097476
  1. 61
      src/stratifier.c

61
src/stratifier.c

@ -1727,14 +1727,27 @@ static inline bool client_active(stratum_instance_t *client)
return (client->authorised && !client->dropped);
}
/* Ask the connector asynchronously to send us dropclient commands if this
* client no longer exists. */
static void connector_test_client(ckpool_t *ckp, const int64_t id)
{
char buf[256];
LOGDEBUG("Stratifier requesting connector test client %"PRId64, id);
snprintf(buf, 255, "testclient=%"PRId64, id);
async_send_proc(ckp, ckp->connector, buf);
}
/* For creating a list of sends without locking that can then be concatenated
* to the stratum_sends list. Minimises locking and avoids taking recursive
* locks. Sends only to sdata bound clients (everyone in ckpool) */
static void stratum_broadcast(sdata_t *sdata, json_t *val)
{
sdata_t *ckp_sdata = sdata->ckp->data;
ckpool_t *ckp = sdata->ckp;
sdata_t *ckp_sdata = ckp->data;
stratum_instance_t *client, *tmp;
ckmsg_t *bulk_send = NULL;
time_t now_t = time(NULL);
ckmsgq_t *ssends;
if (unlikely(!val)) {
@ -1742,6 +1755,7 @@ static void stratum_broadcast(sdata_t *sdata, json_t *val)
return;
}
/* Use this locking as an opportunity to test other clients. */
ck_rlock(&ckp_sdata->instance_lock);
HASH_ITER(hh, ckp_sdata->stratum_instances, client, tmp) {
ckmsg_t *client_msg;
@ -1749,6 +1763,22 @@ static void stratum_broadcast(sdata_t *sdata, json_t *val)
if (sdata != ckp_sdata && client->sdata != sdata)
continue;
/* Test for clients that haven't authed in over a minute and drop them */
if (!client->authorised) {
if (now_t > client->start_time + 60) {
client->dropped = true;
connector_drop_client(ckp, client->id);
}
continue;
}
/* Look for clients that may have been dropped which the stratifer has
* not been informed about and ask the connector of they still exist */
if (client->dropped || client->reconnect) {
connector_test_client(ckp, client->id);
continue;
}
if (!client_active(client))
continue;
client_msg = ckalloc(sizeof(ckmsg_t));
@ -1808,17 +1838,6 @@ static void dec_worker(ckpool_t *ckp, user_instance_t *instance)
mutex_unlock(&sdata->stats_lock);
}
/* Ask the connector asynchronously to send us dropclient commands if this
* client no longer exists. */
static void connector_test_client(ckpool_t *ckp, const int64_t id)
{
char buf[256];
LOGDEBUG("Stratifier requesting connector test client %"PRId64, id);
snprintf(buf, 255, "testclient=%"PRId64, id);
async_send_proc(ckp, ckp->connector, buf);
}
static void drop_client(ckpool_t *ckp, sdata_t *sdata, const int64_t id)
{
stratum_instance_t *client, *tmp;
@ -1828,25 +1847,7 @@ static void drop_client(ckpool_t *ckp, sdata_t *sdata, const int64_t id)
LOGINFO("Stratifier asked to drop client %"PRId64, id);
/* Use this locking as an opportunity to test other clients. */
ck_ilock(&sdata->instance_lock);
/* Test for clients that haven't authed in over a minute and drop them */
HASH_ITER(hh, sdata->stratum_instances, client, tmp) {
if (client->authorised)
continue;
if (now_t > client->start_time + 60) {
client->dropped = true;
connector_drop_client(ckp, client->id);
}
}
/* Look for clients that may have been dropped which the stratifer has
* not been informed about and ask the connector of they still exist */
HASH_ITER(hh, sdata->stratum_instances, client, tmp) {
if (client->dropped || client->reconnect)
connector_test_client(ckp, client->id);
}
client = __instance_by_id(sdata, id);
/* Upgrade to write lock */
ck_ulock(&sdata->instance_lock);

Loading…
Cancel
Save