Browse Source

Remove the linked list of dead clients and maintain a linked list of all workers by user, and store stats per combined workername

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

61
src/stratifier.c

@ -194,6 +194,14 @@ static ckmsgq_t *stxnq; // Transaction requests
static int64_t user_instance_id; static int64_t user_instance_id;
struct user_instance;
struct worker_instance;
struct stratum_instance;
typedef struct user_instance user_instance_t;
typedef struct worker_instance worker_instance_t;
typedef struct stratum_instance stratum_instance_t;
struct user_instance { struct user_instance {
UT_hash_handle hh; UT_hash_handle hh;
char username[128]; char username[128];
@ -201,6 +209,9 @@ struct user_instance {
char *secondaryuserid; char *secondaryuserid;
bool btcaddress; bool btcaddress;
/* A linked list of all connected instances of this user */
stratum_instance_t *instances;
int workers; int workers;
double dsps1; /* Diff shares per second, 1 minute rolling average */ double dsps1; /* Diff shares per second, 1 minute rolling average */
@ -210,18 +221,24 @@ struct user_instance {
tv_t last_share; tv_t last_share;
}; };
typedef struct user_instance user_instance_t;
static user_instance_t *user_instances; static user_instance_t *user_instances;
typedef struct stratum_instance stratum_instance_t; /* Combined data from workers with the same workername */
struct worker_instance {
double dsps1;
double dsps5;
double dsps60;
double dsps1440;
tv_t last_share;
int64_t mindiff; /* User chosen mindiff */
};
/* Per client stratum instance == workers */ /* Per client stratum instance == workers */
struct stratum_instance { struct stratum_instance {
UT_hash_handle hh; UT_hash_handle hh;
int64_t id; int64_t id;
/* For the dead instances linked list */
stratum_instance_t *next; stratum_instance_t *next;
stratum_instance_t *prev; stratum_instance_t *prev;
@ -250,6 +267,8 @@ struct stratum_instance {
bool notified_idle; bool notified_idle;
user_instance_t *user_instance; user_instance_t *user_instance;
worker_instance_t *worker_instance;
char *useragent; char *useragent;
char *workername; char *workername;
int64_t user_id; int64_t user_id;
@ -263,7 +282,6 @@ struct stratum_instance {
* is sorted by enonce1_64. */ * is sorted by enonce1_64. */
static stratum_instance_t *stratum_instances; static stratum_instance_t *stratum_instances;
static stratum_instance_t *disconnected_instances; static stratum_instance_t *disconnected_instances;
static stratum_instance_t *dead_instances;
/* Protects both stratum and user instances */ /* Protects both stratum and user instances */
static cklock_t instance_lock; static cklock_t instance_lock;
@ -1087,8 +1105,6 @@ static void drop_client(int64_t id)
/* Only keep around one copy of the old client in server mode */ /* Only keep around one copy of the old client in server mode */
if (!client->ckp->proxy && !old_client && client->enonce1_64) if (!client->ckp->proxy && !old_client && client->enonce1_64)
HASH_ADD(hh, disconnected_instances, enonce1_64, sizeof(uint64_t), client); HASH_ADD(hh, disconnected_instances, enonce1_64, sizeof(uint64_t), client);
else // Keep around instance so we don't get a dereference
LL_PREPEND(dead_instances, client);
ck_dwilock(&instance_lock); ck_dwilock(&instance_lock);
} }
ck_uilock(&instance_lock); ck_uilock(&instance_lock);
@ -1454,10 +1470,12 @@ static bool test_address(ckpool_t *ckp, const char *address)
/* This simply strips off the first part of the workername and matches it to a /* This simply strips off the first part of the workername and matches it to a
* user or creates a new one. */ * user or creates a new one. */
static user_instance_t *authorise_user(ckpool_t *ckp, const char *workername) static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client,
const char *workername)
{ {
char *base_username = strdupa(workername), *username; char *base_username = strdupa(workername), *username;
user_instance_t *instance; user_instance_t *instance;
stratum_instance_t *tmp;
bool new = false; bool new = false;
int len; int len;
@ -1468,7 +1486,7 @@ static user_instance_t *authorise_user(ckpool_t *ckp, const char *workername)
if (unlikely(len > 127)) if (unlikely(len > 127))
username[127] = '\0'; username[127] = '\0';
ck_ilock(&instance_lock); ck_wlock(&instance_lock);
HASH_FIND_STR(user_instances, username, instance); HASH_FIND_STR(user_instances, username, instance);
if (!instance) { if (!instance) {
/* New user instance. Secondary user id will be NULL */ /* New user instance. Secondary user id will be NULL */
@ -1476,12 +1494,21 @@ static user_instance_t *authorise_user(ckpool_t *ckp, const char *workername)
strcpy(instance->username, username); strcpy(instance->username, username);
new = true; new = true;
ck_ulock(&instance_lock);
instance->id = user_instance_id++; instance->id = user_instance_id++;
HASH_ADD_STR(user_instances, username, instance); HASH_ADD_STR(user_instances, username, instance);
ck_dwilock(&instance_lock);
} }
ck_uilock(&instance_lock); DL_FOREACH(instance->instances, tmp) {
if (!safecmp(workername, tmp->workername)) {
client->worker_instance = tmp->worker_instance;
break;
}
}
/* Create one worker instance for combined data from workers of the
* same name */
if (!client->worker_instance)
client->worker_instance = ckzalloc(sizeof(worker_instance_t));
DL_APPEND(instance->instances, client);
ck_wunlock(&instance_lock);
if (new && !ckp->proxy) { if (new && !ckp->proxy) {
/* Is this a btc address based username? */ /* Is this a btc address based username? */
@ -1631,7 +1658,7 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j
*err_val = json_string("Invalid character in username"); *err_val = json_string("Invalid character in username");
goto out; goto out;
} }
user_instance = client->user_instance = authorise_user(client->ckp, buf); user_instance = client->user_instance = generate_user(client->ckp, client, buf);
client->user_id = user_instance->id; client->user_id = user_instance->id;
ts_realtime(&now); ts_realtime(&now);
client->start_time = now.tv_sec; client->start_time = now.tv_sec;
@ -1701,6 +1728,7 @@ static double sane_tdiff(tv_t *end, tv_t *start)
static void add_submit(ckpool_t *ckp, stratum_instance_t *client, int diff, bool valid) static void add_submit(ckpool_t *ckp, stratum_instance_t *client, int diff, bool valid)
{ {
worker_instance_t *worker = client->worker_instance;
double tdiff, bdiff, dsps, drr, network_diff, bias; double tdiff, bdiff, dsps, drr, network_diff, bias;
user_instance_t *instance = client->user_instance; user_instance_t *instance = client->user_instance;
int64_t next_blockid, optimal; int64_t next_blockid, optimal;
@ -1733,6 +1761,13 @@ static void add_submit(ckpool_t *ckp, stratum_instance_t *client, int diff, bool
decay_time(&client->dsps1440, diff, tdiff, 86400); decay_time(&client->dsps1440, diff, tdiff, 86400);
copy_tv(&client->last_share, &now_t); copy_tv(&client->last_share, &now_t);
tdiff = sane_tdiff(&now_t, &worker->last_share);
decay_time(&worker->dsps1, diff, tdiff, 60);
decay_time(&worker->dsps5, diff, tdiff, 300);
decay_time(&worker->dsps60, diff, tdiff, 3600);
decay_time(&worker->dsps1440, diff, tdiff, 86400);
copy_tv(&worker->last_share, &now_t);
tdiff = sane_tdiff(&now_t, &instance->last_share); tdiff = sane_tdiff(&now_t, &instance->last_share);
decay_time(&instance->dsps1, diff, tdiff, 60); decay_time(&instance->dsps1, diff, tdiff, 60);
decay_time(&instance->dsps5, diff, tdiff, 300); decay_time(&instance->dsps5, diff, tdiff, 300);

Loading…
Cancel
Save