[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);
+						}
 					}
 				}
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/