[vhffs-dev] [1339] added quick and dirty rate limiter |
[ Thread Index |
Date Index
| More vhffs.org/vhffs-dev Archives
]
Revision: 1339
Author: gradator
Date: 2009-02-17 03:13:40 +0100 (Tue, 17 Feb 2009)
Log Message:
-----------
added quick and dirty rate limiter
Modified Paths:
--------------
trunk/vhffs-fssync/vhffsfssync_master.c
trunk/vhffs-fssync/vhffsfssync_slave.c
Modified: trunk/vhffs-fssync/vhffsfssync_master.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_master.c 2009-02-16 23:09:47 UTC (rev 1338)
+++ trunk/vhffs-fssync/vhffsfssync_master.c 2009-02-17 02:13:40 UTC (rev 1339)
@@ -1533,10 +1533,10 @@
static void usage_exit(int ret_code, char *progname) {
printf ("Usage: %s [OPTION]... DIRECTORY\n"
- "Remote synchronous file-copying tool, this is the client (the slave)\n\n"
+ "Remote synchronous file-copying tool, this is the server (the master)\n\n"
" -f, --foreground\tDon't daemonise the server, display errors on the console\n"
- " -b, --bind\t\tListen to the specified IP address\n"
- " -p, --port\t\tListen to this port\n"
+ " -b, --bind=IP\t\tListen to the specified IP address\n"
+ " -p, --port=PORT\tListen to this port\n"
" -h, --help\t\tDisplay this help and exit\n"
" -v, --version\t\tOutput version information and exit\n",
progname);
Modified: trunk/vhffs-fssync/vhffsfssync_slave.c
===================================================================
--- trunk/vhffs-fssync/vhffsfssync_slave.c 2009-02-16 23:09:47 UTC (rev 1338)
+++ trunk/vhffs-fssync/vhffsfssync_slave.c 2009-02-17 02:13:40 UTC (rev 1339)
@@ -75,6 +75,10 @@
uint32_t messages_end;
GHashTable *openfiles;
+
+ double limitrate_speed;
+ double limitrate_sleep;
+ double limitrate_timeprev;
} vhffsfssync_conn;
// network protos
@@ -90,6 +94,7 @@
int vhffsfssync_parse(vhffsfssync_conn *conn);
// misc
+double vhffsfssync_time();
static void usage_exit(int ret_code, char *progname);
/* ------------------------------------------------------------ */
@@ -622,10 +627,18 @@
}
+double vhffsfssync_time() {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec + tv.tv_usec / 1e6;
+}
+
+
static void usage_exit(int ret_code, char *progname) {
printf ("Usage: %s [OPTION]... HOST[:PORT] DIRECTORY\n"
"Remote synchronous file-copying tool, this is the client (the slave)\n\n"
" -f, --foreground\tDon't daemonise the client, display errors on the console\n"
+ " -r, --limit-rate=kB/s\tLimit I/O bandwith; kBytes per second\n"
" -h, --help\t\tDisplay this help and exit\n"
" -v, --version\t\tOutput version information and exit\n",
progname);
@@ -643,9 +656,11 @@
char *host = NULL;
int port = 4567;
char *root = NULL;
+ int limitrate = 0;
struct option long_options[] = {
{ "foreground", no_argument, NULL, 'f' },
+ { "limit-rate", required_argument, NULL, 'r' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ 0, 0, 0, 0 }
@@ -653,7 +668,7 @@
while(1) {
int option_index = 0, c;
- c = getopt_long(argc, argv, "fhv", long_options, &option_index);
+ c = getopt_long(argc, argv, "fr:hv", long_options, &option_index);
if(c == -1)
break;
@@ -662,6 +677,10 @@
foreground = 1;
break;
+ case 'r':
+ limitrate = atoi(optarg)*1000;
+ break;
+
case 'h':
usage_exit(0, argv[0]);
@@ -721,6 +740,9 @@
conn->messages_begin = 0;
conn->messages_end = 0;
conn->openfiles = NULL;
+ conn->limitrate_speed = (double)limitrate;
+ conn->limitrate_sleep = 0;
+ conn->limitrate_timeprev = vhffsfssync_time();
/* -- main loop -- */
while(1) {
@@ -751,6 +773,10 @@
conn->recvbuf_end = 0;
conn->chunk_stilltoread = 0;
+ conn->limitrate_speed = (double)limitrate;
+ conn->limitrate_sleep = 0;
+ conn->limitrate_timeprev = vhffsfssync_time();
+
/* connect */
inet_aton(host, &conn->sockaddr.sin_addr);
conn->sockaddr.sin_family = AF_INET;
@@ -833,6 +859,27 @@
conn->recvbuf_end += len;
if( vhffsfssync_parse(conn) )
goto disconnected;
+
+ if(limitrate > 0) {
+ double current, delta, delta_t, a;
+
+ // computing download rate
+ current = vhffsfssync_time();
+ delta_t = current - conn->limitrate_timeprev;
+ conn->limitrate_timeprev = current;
+
+ a = delta_t/2.0; // consider elapsed time, speed is roughly computed over 2 seconds
+ if(a > 1.0) a = 1.0;
+ else if(a < 0.0) a = 0.0; // might happens
+ conn->limitrate_speed = (conn->limitrate_speed * (1.0-a)) + (((double)len / delta_t) * a);
+ //printf("%.2f MB/s\n", conn->limitrate_speed/1000/1000 );
+
+ delta = conn->limitrate_speed - (double)limitrate; // delta is in bytes/s
+ conn->limitrate_sleep += delta * 0.01;
+ //printf("%.2f ms\n", conn->limitrate_sleep/1000 );
+ if(conn->limitrate_sleep > 1000000.0) conn->limitrate_sleep = 1000000.0;
+ if(conn->limitrate_sleep > 0.0) usleep((int)conn->limitrate_sleep);
+ }
}
}