update_stats program

svn path=/trunk/boinc/; revision=1030
This commit is contained in:
Eric Heien 2003-03-08 00:09:40 +00:00
parent afc9133ab1
commit 048ba6b6c9
18 changed files with 386 additions and 144 deletions

View File

@ -3732,3 +3732,27 @@ David Mar 6 2003
util.C,h
sched/
*.C
Eric March 7, 2003
- Moved common functions (write_log, check_trigger, update_average)
into sched_util.C
- Added stop_server checking to more server programs
- Added update_stats program to periodically update exponential average
credit for users and hosts, and to update team credit by summing member credit
- Added db_sum, db_query_double to retrieve sums of columns (used by update_stats)
- Added db_user_sum_team_expavg_credit, db_user_sum_team_total_credit,
db_user_count_team for updating team statistics
- Confirmed that current exponential average algorithm is correct
db/
mysql_util.C,h
db_mysql.C
db.h
html_user/
top_teams.php
sched/
Makefile.in
*.C
sched_util.C,h (added)
update_stats.C (added)

View File

@ -345,12 +345,15 @@ extern int db_user_new(USER&);
extern int db_user(int, USER&);
extern int db_user_update(USER&);
extern int db_user_count(int&);
extern int db_user_count_team(TEAM&, int&);
extern int db_user_lookup_auth(USER&);
extern int db_user_lookup_email_addr(USER&);
extern int db_user_enum_id(USER&);
extern int db_user_enum_total_credit(USER&);
extern int db_user_enum_expavg_credit(USER&);
extern int db_user_enum_teamid(USER&);
extern int db_user_sum_team_expavg_credit(TEAM&,double&);
extern int db_user_sum_team_total_credit(TEAM&,double&);
extern int db_team(int, TEAM&);
extern int db_team_new(TEAM&);

View File

@ -619,6 +619,13 @@ int db_user_count(int& n) {
return boinc_db.db_count(&n, "*", TYPE_USER);
}
int db_user_count_team(TEAM& p, int& n) {
char buf[256];
sprintf(buf, "teamid=%d", p.id);
return boinc_db.db_count(&n, "*", TYPE_USER, buf);
}
int db_user_lookup_email_addr(USER& p) {
char buf[256];
@ -650,6 +657,20 @@ int db_user_enum_teamid(USER& p) {
return boinc_db.db_enum(e, &p, TYPE_USER, buf);
}
int db_user_sum_team_expavg_credit(TEAM& p, double& n) {
char buf[256];
sprintf(buf, "teamid=%d", p.id);
return boinc_db.db_sum(&n, "expavg_credit", TYPE_USER, buf);
}
int db_user_sum_team_total_credit(TEAM& p, double& n) {
char buf[256];
sprintf(buf, "teamid=%d", p.id);
return boinc_db.db_sum(&n, "total_credit", TYPE_USER, buf);
}
////////// TEAM /////////
int db_team(int i, TEAM& p) {

View File

@ -194,6 +194,17 @@ int MYSQL_DB::db_query_int(int* ip, char* query) {
return 0;
}
int MYSQL_DB::db_query_double(double* dp, char* query) {
mysql_query(mp, query);
rp = mysql_store_result(mp);
if (!rp) return -1;
row = mysql_fetch_row(rp);
if (!row) return -1;
*dp = atof(row[0]);
mysql_free_result(rp);
return 0;
}
int MYSQL_DB::db_count(int* np, char* what, int type, char* clause) {
char buf[MAX_QUERY_LEN];
sprintf(buf, "select count(%s) from %s ", what, table_name[type]);
@ -201,6 +212,13 @@ int MYSQL_DB::db_count(int* np, char* what, int type, char* clause) {
return db_query_int(np, buf);
}
int MYSQL_DB::db_sum(double* np, char* what, int type, char* clause) {
char buf[MAX_QUERY_LEN];
sprintf(buf, "select sum(%s) from %s ", what, table_name[type]);
if (clause) strcat(buf, clause);
return db_query_double(np, buf);
}
int MYSQL_DB::db_query(char* p) {
return mysql_query(mp, p);
}

View File

@ -50,6 +50,8 @@ public:
int db_enum(ENUM&, void*, int, char* clause=0, int limit=0);
int db_enum_field(ENUM&, int, char*, char*);
int db_query_int(int*, char*);
int db_query_double(double*, char*);
int db_count(int*, char*, int, char* clause=0);
int db_sum(double*, char*, int, char* clause=0);
int db_query(char*);
};

View File

@ -20,30 +20,6 @@ function show_team_row($team) {
db_init();
// update team stats; eventually this must be moved
// to a separate program
//
$result = mysql_query("select * from team");
while ($team = mysql_fetch_object($result)) {
$query = "select sum(total_credit) from user where teamid = $team->id";
$result2 = mysql_query($query);
$total_credit_sum = mysql_result($result2, 0);
$query = "select sum(expavg_credit) from user where teamid = $team->id";
$result2 = mysql_query($query);
$expavg_credit_sum = mysql_result($result2, 0);
$query = "select count(*) from user where teamid = $team->id";
$result2 = mysql_query($query);
$nmembers = mysql_result($result2, 0);
$total_credit = $total_credit_sum;
$expavg_credit = $expavg_credit_sum;
$query = "update team set nusers=$nmembers, total_credit=$total_credit, expavg_credit=$expavg_credit where id=$team->id";
$result2 = mysql_query($query);
}
mysql_free_result($result);
page_head("Top teams");
$result = mysql_query("select * from team order by expavg_credit desc, total_credit desc");
team_table_start();

View File

@ -18,7 +18,7 @@ CC = g++ $(CFLAGS)
CLIBS = @LIBS@
PROGS = cgi feeder show_shmem file_upload_handler validate_test make_work result_retry file_deleter assimilator db_dump start_servers
PROGS = cgi feeder show_shmem file_upload_handler validate_test make_work result_retry file_deleter assimilator db_dump update_stats start_servers
all: $(PROGS)
@ -27,6 +27,7 @@ CGI_OBJS = \
main.o \
sched_shmem.o \
server_types.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -37,6 +38,7 @@ CGI_OBJS = \
FEEDER_OBJS = \
feeder.o \
sched_shmem.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -47,6 +49,7 @@ FEEDER_OBJS = \
SHOW_SHMEM_OBJS = \
show_shmem.o \
sched_shmem.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -67,6 +70,7 @@ FILE_UPLOAD_OBJS = \
VALIDATE_OBJS = \
validate.o \
validate_test.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -75,6 +79,7 @@ VALIDATE_OBJS = \
FILE_DELETER_OBJS = \
file_deleter.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -84,6 +89,7 @@ FILE_DELETER_OBJS = \
ASSIMILATOR_OBJS = \
assimilator.o \
assimilate_handler.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -92,6 +98,7 @@ ASSIMILATOR_OBJS = \
MAKE_WORK_OBJS = \
make_work.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -106,6 +113,7 @@ MAKE_WORK_OBJS = \
RESULT_RETRY_OBJS = \
result_retry.o \
sched_util.o \
config.o \
../db/db_mysql.o \
../db/mysql_util.o \
@ -123,9 +131,19 @@ DB_DUMP_OBJS = \
../db/mysql_util.o \
../lib/parse.o \
../lib/util.o \
sched_util.o \
config.o \
db_dump.o
UPDATE_STATS_OBJS = \
../db/db_mysql.o \
../db/mysql_util.o \
../lib/parse.o \
../lib/util.o \
sched_util.o \
config.o \
update_stats.o
START_SERVERS_OBJS = \
../lib/util.o \
../lib/parse.o \
@ -197,6 +215,9 @@ assimilator: $(ASSIMILATOR_OBJS)
db_dump: $(DB_DUMP_OBJS)
$(CC) $(DB_DUMP_OBJS) $(MYSQL_LIBS) $(CLIBS) -o db_dump
update_stats: $(UPDATE_STATS_OBJS)
$(CC) $(UPDATE_STATS_OBJS) $(MYSQL_LIBS) $(CLIBS) -o update_stats
start_servers: $(START_SERVERS_OBJS)
$(CC) $(START_SERVERS_OBJS) $(CLIBS) -o start_servers

View File

@ -27,16 +27,13 @@
#include "parse.h"
#include "util.h"
#include "config.h"
#include "sched_util.h"
#include "assimilate_handler.h"
#define ASSIMILATOR_LOCKFILE "assimilator.out"
CONFIG config;
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
// assimilate all WUs that need it
// return nonzero if did anything
//
@ -48,6 +45,8 @@ bool do_pass(APP& app) {
char buf[MAX_BLOB_SIZE];
unsigned int i;
check_stop_trigger();
wu.appid = app.id;
wu.assimilate_state = ASSIMILATE_READY;
while (!db_workunit_enum_app_assimilate_state(wu)) {
@ -118,6 +117,7 @@ int main(int argc, char** argv) {
int i;
char buf[256];
check_stop_trigger();
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-asynch")) {
asynch = true;

View File

@ -19,7 +19,7 @@
// db_dump: dump database views in XML format
//
// usage: db_dump [-dir path] [-update_teams] [-gzip] [-zip]
// usage: db_dump [-dir path] [-gzip] [-zip]
// files:
// NOTE: the goal is to make the full DB available (view *_id files)
@ -60,6 +60,7 @@
#include "db.h"
#include "util.h"
#include "config.h"
#include "sched_util.h"
#define LOCKFILE "db_dump.out"
@ -69,31 +70,6 @@
bool zip_files = false;
char zip_cmd[256];
// fill in the nusers, total_credit and expavg_credit fields
// of the team table.
// This may take a while; don't do it often
//
int update_teams() {
TEAM team;
USER user;
int retval;
while (!db_team_enum(team)) {
team.nusers = 0;
team.total_credit = 0;
team.expavg_credit = 0;
user.teamid = team.id;
while (!db_user_enum_teamid(user)) {
team.nusers++;
team.total_credit += user.total_credit;
team.expavg_credit += user.expavg_credit;
}
retval = db_team_update(team);
if (retval) return retval;
}
return 0;
}
void write_host(HOST& host, FILE* f, bool detail, bool show_user) {
fprintf(f,
"<host>\n"
@ -545,15 +521,14 @@ int tables_file() {
int main(int argc, char** argv) {
CONFIG config;
int retval, i;
bool do_update_teams = false;
char dir[256];
check_stop_trigger();
strcpy(dir, "");
strcpy(zip_cmd, "");
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-update_teams")) {
do_update_teams = true;
} else if (!strcmp(argv[i], "-dir")) {
if (!strcmp(argv[i], "-dir")) {
strcpy(dir, argv[++i]);
} else if (!strcmp(argv[i], "-gzip")) {
zip_files = true;
@ -587,13 +562,6 @@ int main(int argc, char** argv) {
exit(1);
}
}
if (do_update_teams) {
retval = update_teams();
if (retval) {
fprintf(stderr, "update_teams failed: %d\n", retval);
exit(1);
}
}
tables_file();
team_total_credit();
team_expavg_credit();

View File

@ -57,22 +57,18 @@
#include "util.h"
#include "config.h"
#include "sched_shmem.h"
#include "sched_util.h"
#define RESULTS_PER_ENUM 100
#define STOP_SERVER_FILENAME "stop_server"
#define REREAD_DB_FILENAME "reread_db"
#define LOCKFILE "feeder.out"
CONFIG config;
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
int check_triggers(SCHED_SHMEM* ssp) {
FILE* f;
f = fopen(STOP_SERVER_FILENAME, "r");
f = fopen(STOP_TRIGGER_FILENAME, "r");
if (f) {
fclose(f);
detach_shmem((void*)ssp);
@ -204,7 +200,6 @@ int main(int argc, char** argv) {
void* p;
char buf[256];
unlink(STOP_SERVER_FILENAME);
unlink(REREAD_DB_FILENAME);
retval = config.parse_file();

View File

@ -29,15 +29,12 @@
#include "parse.h"
#include "util.h"
#include "config.h"
#include "sched_util.h"
#define LOCKFILE "file_deleter.out"
CONFIG config;
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
int wu_delete_files(WORKUNIT& wu) {
char* p;
char filename[256], pathname[256], buf[MAX_BLOB_SIZE], logbuf[256];
@ -101,6 +98,8 @@ bool do_pass() {
RESULT result;
bool did_something = false;
check_stop_trigger();
wu.file_delete_state = FILE_DELETE_READY;
while (!db_workunit_enum_file_delete_state(wu)) {
did_something = true;
@ -125,6 +124,7 @@ int main(int argc, char** argv) {
int i;
char buf[256];
check_stop_trigger();
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-asynch")) {
asynch = true;

View File

@ -48,10 +48,6 @@ bool use_files = false; // use disk files for req/reply msgs (for debugging)
PROJECT gproject;
CONFIG config;
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
int main() {
FILE* fin, *fout;
int i, retval, pid;

View File

@ -40,18 +40,14 @@
#include "backend_lib.h"
#include "config.h"
#include "parse.h"
#include "sched_util.h"
#define TRIGGER_FILENAME "stop_server"
#define LOCKFILE "make_work.out"
int cushion = 10;
int redundancy = 10;
char wu_name[256], result_template_file[256];
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
// edit a WU XML doc, replacing one filename by another
// (should appear twice, within <file_info> and <file_ref>)
// Also patch the download URL (redundant)
@ -85,12 +81,6 @@ void replace_file_name(
}
}
void check_trigger() {
FILE* f = fopen(TRIGGER_FILENAME, "r");
if (!f) return;
exit(0);
}
void make_work() {
CONFIG config;
char * p;
@ -200,7 +190,7 @@ void make_work() {
sprintf(buf, "added result: %s_%s\n", wu.name, suffix);
write_log(buf);
nresults_left--;
check_trigger();
check_stop_trigger();
}
}
@ -208,7 +198,7 @@ int main(int argc, char** argv) {
bool asynch = false;
int i;
unlink(TRIGGER_FILENAME);
check_stop_trigger();
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-asynch")) {
asynch = true;

View File

@ -39,8 +39,8 @@ using namespace std;
#include "util.h"
#include "backend_lib.h"
#include "config.h"
#include "sched_util.h"
#define TRIGGER_FILENAME "stop_server"
#define LOCKFILE "result_retry.out"
int max_errors = 999;
@ -51,16 +51,6 @@ CONFIG config;
R_RSA_PRIVATE_KEY key;
char app_name[256];
void check_trigger() {
FILE* f = fopen(TRIGGER_FILENAME, "r");
if (!f) return;
exit(0);
}
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
// The scheme for generating unique output filenames is as follows.
// If the original filename is of the form x__y,
// then y is replaced with a string of the form time_seqno,
@ -325,7 +315,7 @@ void main_loop(bool one_pass) {
did_something = do_pass(app);
if (one_pass) break;
if (!did_something) sleep(1);
check_trigger();
check_stop_trigger();
}
}
@ -334,6 +324,7 @@ int main(int argc, char** argv) {
bool asynch = false, one_pass=false;
char path[256];
check_stop_trigger();
startup_time = time(0);
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-app")) {

99
sched/sched_util.C Normal file
View File

@ -0,0 +1,99 @@
// The contents of this file are subject to the Mozilla Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is the Berkeley Open Infrastructure for Network Computing.
//
// The Initial Developer of the Original Code is the SETI@home project.
// Portions created by the SETI@home project are Copyright (C) 2002
// University of California at Berkeley. All Rights Reserved.
//
// Contributor(s):
//
#include <strings.h>
#include "parse.h"
#include "util.h"
#include "main.h"
#include "sched_util.h"
#include "server_types.h"
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
void check_stop_trigger() {
FILE* f = fopen(STOP_TRIGGER_FILENAME, "r");
if (!f) return;
exit(0);
}
// fill in the nusers, total_credit and expavg_credit fields
// of the team table.
// This may take a while; don't do it often
//
int update_teams() {
TEAM team;
int retval;
while (!db_team_enum(team)) {
retval = get_team_credit(team);
if (retval) return retval;
// update the team record
retval = db_team_update(team);
if (retval) return retval;
}
return 0;
}
int get_team_credit(TEAM &t) {
int nusers;
double expavg_credit, total_credit;
int retval;
// count the number of users on a team
retval = db_user_count_team(t, nusers);
if (retval) return retval;
// get the summed credit values for a team
retval = db_user_sum_team_expavg_credit(t, expavg_credit);
if (retval) return retval;
retval = db_user_sum_team_total_credit(t, total_credit);
if (retval) return retval;
t.nusers = nusers;
t.total_credit = total_credit;
t.expavg_credit = expavg_credit;
return 0;
}
// update an exponential average of credit per second.
//
void update_average(double credit_assigned_time, double credit, double& avg, double& avg_time) {
time_t now = time(0);
// decrease existing average according to how long it's been
// since it was computed
//
if (avg_time) {
double deltat = now - avg_time;
avg *= exp(-deltat*ALPHA);
}
if (credit_assigned_time) {
double deltat = now - credit_assigned_time;
// Add (credit)/(number of days to return result) to credit, which
// is the average number of cobblestones per day
avg += credit/(deltat/86400);
}
avg_time = now;
}

49
sched/sched_util.h Normal file
View File

@ -0,0 +1,49 @@
// The contents of this file are subject to the Mozilla Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is the Berkeley Open Infrastructure for Network Computing.
//
// The Initial Developer of the Original Code is the SETI@home project.
// Portions created by the SETI@home project are Copyright (C) 2002
// University of California at Berkeley. All Rights Reserved.
//
// Contributor(s):
//
#ifndef _SCHED_UTIL_
#define _SCHED_UTIL_
#include <math.h>
// "average credit" uses an exponential decay so that recent
// activity is weighted more heavily.
// H is the "half-life" period: the average goes down by 1/2
// if idle for this period.
// Specifically, the weighting function W(t) is
// W(t) = exp(t/(H*log(2))*H*log(2).
// The average credit is the sum of X*W(t(X))
// over units of credit X that were granted t(X) time ago.
#define LOG2 M_LN2
// log(2)
#define SECONDS_IN_DAY (3600*24)
#define AVG_HALF_LIFE (SECONDS_IN_DAY*7)
#define ALPHA (LOG2/AVG_HALF_LIFE)
#define STOP_TRIGGER_FILENAME "stop_server"
extern void write_log(char*);
extern void check_stop_trigger();
extern int get_team_credit(TEAM&);
extern int update_teams();
extern void update_average(double, double, double&, double&);
#endif

123
sched/update_stats.C Normal file
View File

@ -0,0 +1,123 @@
// The contents of this file are subject to the Mozilla Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is the Berkeley Open Infrastructure for Network Computing.
//
// The Initial Developer of the Original Code is the SETI@home project.
// Portions created by the SETI@home project are Copyright (C) 2002
// University of California at Berkeley. All Rights Reserved.
//
// Contributor(s):
//
// update_stats: update exponential average credit for users and hosts,
// and calculate total users/credit for teams
//
// usage: update_stats [-update_teams] [-update_users] [-update_hosts]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "db.h"
#include "util.h"
#include "config.h"
#include "sched_util.h"
#define LOCKFILE "update_stats.out"
int update_users() {
USER user;
int retval;
while (!db_user_enum_id(user)) {
update_average(0, 0, user.expavg_credit, user.expavg_time);
retval = db_user_update(user);
if (retval) return retval;
}
return 0;
}
int update_hosts() {
HOST host;
int retval;
while (!db_host_enum_id(host)) {
update_average(0, 0, host.expavg_credit, host.expavg_time);
retval = db_host_update(host);
if (retval) return retval;
}
return 0;
}
int main(int argc, char** argv) {
CONFIG config;
int retval, i;
bool do_update_teams = false;
bool do_update_users = false;
bool do_update_hosts = false;
check_stop_trigger();
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-update_teams")) {
do_update_teams = true;
} else if (!strcmp(argv[i], "-update_users")) {
do_update_users = true;
} else if (!strcmp(argv[i], "-update_hosts")) {
do_update_hosts = true;
}
}
if (lock_file(LOCKFILE)) {
fprintf(stderr, "Another copy of update_stats is already running\n");
exit(1);
}
retval = config.parse_file();
if (retval) {
fprintf(stderr, "Can't parse config file\n");
exit(1);
}
retval = boinc_db_open(config.db_name, config.db_passwd);
if (retval) {
fprintf(stderr, "Can't open DB\n");
exit(1);
}
if (do_update_teams) {
retval = update_teams();
if (retval) {
fprintf(stderr, "update_teams failed: %d\n", retval);
exit(1);
}
}
if (do_update_users) {
retval = update_users();
if (retval) {
fprintf(stderr, "update_users failed: %d\n", retval);
exit(1);
}
}
if (do_update_hosts) {
retval = update_hosts();
if (retval) {
fprintf(stderr, "update_hosts failed: %d\n", retval);
exit(1);
}
}
return 0;
}

View File

@ -48,6 +48,7 @@ using namespace std;
#include "db.h"
#include "util.h"
#include "config.h"
#include "sched_util.h"
#define LOCKFILE "validate.out"
@ -58,44 +59,6 @@ CONFIG config;
char app_name[256];
int min_quorum;
// "average credit" uses an exponential decay so that recent
// activity is weighted more heavily.
// H is the "half-life" period: the average goes down by 1/2
// if idle for this period.
// Specifically, the weighting function W(t) is
// W(t) = exp(t/(H*log(2))*H*log(2).
// The average credit is the sum of X*W(t(X))
// over units of credit X that were granted t(X) time ago.
#define LOG2 M_LN2
// log(2)
#define SECONDS_IN_DAY (3600*24)
#define AVG_HALF_LIFE (SECONDS_IN_DAY*7)
#define ALPHA (LOG2/AVG_HALF_LIFE)
void write_log(char* p) {
fprintf(stderr, "%s: %s", timestamp(), p);
}
// update an exponential average of credit per second.
//
void update_average(double credit_assigned_time, double credit, double& avg, double& avg_time) {
time_t now = time(0);
// decrease existing average according to how long it's been
// since it was computed
//
if (avg_time) {
double deltat = now - avg_time;
avg *= exp(-deltat*ALPHA);
}
double deltat = now - credit_assigned_time;
// Add (credit)/(number of days to return result) to credit, which
// is the average number of cobblestones per day
avg += credit/(deltat/86400);
avg_time = now;
}
// here when a result has been validated;
// grant credit to host and user
//
@ -301,6 +264,7 @@ int main_loop(bool one_pass) {
}
while (1) {
check_stop_trigger();
did_something = do_validate_scan(app, min_quorum);
if (one_pass) break;
if (!did_something) {
@ -316,6 +280,8 @@ int main(int argc, char** argv) {
bool asynch = false, one_pass = false;
char buf[256];
check_stop_trigger();
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-asynch")) {
asynch = true;