[Red5commits] [1743] Updated the API and implementation of Bandwidth Control Framework.Provided a te

sgong luke at codegent.com
Mon Feb 26 00:32:20 EST 2007


Updated the API and implementation of Bandwidth Control Framework.
Provided a testcase for it.


Timestamp: 02/24/07 00:59:36 EST (2 days ago) 
Change: 1743 
Author: sgong

Files (see diff or trac for details): 
java/server/trunk/.classpath
java/server/trunk/conf/red5-common.xml
java/server/trunk/lib/GroboUtils-5-core.jar
java/server/trunk/lib/spring-mock.jar
java/server/trunk/src/org/red5/server/Client.java
java/server/trunk/src/org/red5/server/api/IBWControllable.java
java/server/trunk/src/org/red5/server/api/IBandwidthConfigure.java
java/server/trunk/src/org/red5/server/api/IClient.java
java/server/trunk/src/org/red5/server/api/IConnectionBWConfig.java
java/server/trunk/src/org/red5/server/api/stream/IClientStream.java
java/server/trunk/src/org/red5/server/api/stream/IStreamCapableConnection.java
java/server/trunk/src/org/red5/server/api/stream/support/SimpleBandwidthConfigure.java
java/server/trunk/src/org/red5/server/api/stream/support/SimpleConnectionBWConfig.java
java/server/trunk/src/org/red5/server/net/rtmp/RTMPConnection.java
java/server/trunk/src/org/red5/server/stream/AbstractClientStream.java
java/server/trunk/src/org/red5/server/stream/BalancedFlowControlService.java
java/server/trunk/src/org/red5/server/stream/DummyBWControlService.java
java/server/trunk/src/org/red5/server/stream/IBWControlContext.java
java/server/trunk/src/org/red5/server/stream/IBWControlService.java
java/server/trunk/src/org/red5/server/stream/ITokenBucket.java
java/server/trunk/src/org/red5/server/stream/PlaylistSubscriberStream.java
java/server/trunk/src/org/red5/server/stream/SimpleBWControlService.java
java/server/trunk/src/org/red5/server/stream/SimpleFlowControlService.java
java/server/trunk/src/org/red5/server/stream/StreamFlowController.java
java/server/trunk/src/org/red5/server/stream/TokenBucket.java
java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.java
java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.xml
java/server/trunk/webapps/oflaDemo/WEB-INF/src/org/red5/server/webapp/oflaDemo/Application.java


Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/1743

Index: /java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.xml
===================================================================
--- /java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.xml (revision 1743)
+++ /java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.xml (revision 1743)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+<beans>
+	
+	<bean id="BWControlService" class="org.red5.server.stream.SimpleBWControlService" init-method="init">
+		<property name="interval" value="100"/>
+		<property name="defaultCapacity" value="104857600"/> <!-- 100 * 1024 * 1024 -->
+	</bean>
+
+</beans>
Index: /java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.java
===================================================================
--- /java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.java (revision 1743)
+++ /java/server/trunk/test/org/red5/server/stream/test/BandwidthControlServiceTest.java (revision 1743)
@@ -0,0 +1,452 @@
+package org.red5.server.stream.test;
+
+/*
+ * RED5 Open Source Flash Server - http://www.osflash.org/red5
+ *
+ * Copyright (c) 2006-2007 by respective authors (see below). All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 2.1 of the License, or (at your option) any later
+ * version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this library; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
+import net.sourceforge.groboutils.junit.v1.TestRunnable;
+
+import org.red5.server.api.IBWControllable;
+import org.red5.server.api.IBandwidthConfigure;
+import org.red5.server.api.stream.support.SimpleBandwidthConfigure;
+import org.red5.server.stream.IBWControlContext;
+import org.red5.server.stream.IBWControlService;
+import org.red5.server.stream.ITokenBucket;
+import org.red5.server.stream.ITokenBucket.ITokenBucketCallback;
+import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
+
+public class BandwidthControlServiceTest extends
+		AbstractDependencyInjectionSpringContextTests {
+	private boolean isAvailable;
+	private boolean isReset;
+
+	@Override
+	protected String[] getConfigLocations() {
+		return new String[] {"org/red5/server/stream/test/BandwidthControlServiceTest.xml"};
+	}
+	
+	public void testSingleNodeWithParent() throws Exception {
+		IBWControlService bwController =
+			(IBWControlService) applicationContext.getBean(IBWControlService.KEY);
+		ITokenBucketCallback callback = new TokenBucketCallback();
+		
+		Node parent = new Node();
+		parent.setParentBWControllable(null);
+		parent.setBandwidthConfigure(null);
+		IBWControlContext parentContext = bwController.registerBWControllable(parent);
+		
+		Node node = new Node();
+		node.setParentBWControllable(parent);
+		node.setBandwidthConfigure(null);
+		IBWControlContext context = bwController.registerBWControllable(node);
+		ITokenBucket audioBucket = bwController.getAudioBucket(context);
+		ITokenBucket videoBucket = bwController.getVideoBucket(context);
+		ITokenBucket dataBucket = bwController.getDataBucket(context);
+		// no bandwidth configure, all should succeed
+		assertTrue(audioBucket.acquireToken(0, 0));
+		assertTrue(audioBucket.acquireToken(1024, 0));
+		assertTrue(audioBucket.acquireToken(1024 * 1024, 0));
+		assertTrue(videoBucket.acquireToken(0, 0));
+		assertTrue(videoBucket.acquireToken(1024, 0));
+		assertTrue(videoBucket.acquireToken(1024 * 1024, 0));
+		assertTrue(dataBucket.acquireToken(0, 0));
+		assertTrue(dataBucket.acquireToken(1024, 0));
+		assertTrue(dataBucket.acquireToken(1024 * 1024, 0));
+		
+		// use overall bandwidth
+		SimpleBandwidthConfigure config = new SimpleBandwidthConfigure();
+		long[] channelBandwidth = config.getChannelBandwidth();
+		long[] channelInitialBurst = config.getChannelInitialBurst();
+		channelBandwidth[3] = 1024 * 1024; // 1Mbps overall bandwidth
+		channelInitialBurst[3] = 1024 * 1024;
+		parent.setBandwidthConfigure(config);
+		bwController.updateBWConfigure(parentContext);
+		// acquire the initial 1024 * 1024 tokens, should succeed
+		assertTrue(audioBucket.acquireToken(1024 * 1024, 0));
+		// acquire 1024 * 1024 tokens w/o wait, should fail
+		assertFalse(audioBucket.acquireToken(1024 * 1024, 0));
+		assertFalse(videoBucket.acquireToken(1024 * 1024, 0));
+		assertFalse(dataBucket.acquireToken(1024 * 1024, 0));
+		// wait 1.1s for 128KB, should succeed
+		assertTrue(audioBucket.acquireToken(1024 * 1024 / 8, 1100));
+		// wait 0.5s for 128KB, should fail
+		assertFalse(videoBucket.acquireToken(1024 * 1024 / 8, 500));
+		// wait another 0.6s for 128KB, should succeed
+		assertTrue(dataBucket.acquireToken(1024 * 1024 / 8, 600));
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(audioBucket.acquireTokenNonblocking(1024 * 1024 / 8, callback));
+		Thread.sleep(500);
+		assertFalse(isAvailable);
+		assertFalse(isReset);
+		Thread.sleep(600);
+		assertTrue(isAvailable);
+		assertFalse(isReset);
+		
+		// wait 500 then best-effort acquire 128KB
+		// the value should be larger than 0 and less than 128KB
+		audioBucket.acquireTokenBestEffort(1024 * 1024);
+		Thread.sleep(500);
+		long acquired = audioBucket.acquireTokenBestEffort(1024 * 1024 / 8);
+		assertTrue("Acquired " + acquired, acquired > 0 && acquired < 1024 * 1024 / 8);
+		
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(videoBucket.acquireTokenNonblocking(1024 * 1024 / 8, callback));
+		bwController.resetBuckets(context);
+		Thread.sleep(500);
+		assertFalse(isAvailable);
+		assertTrue(isReset);
+		Thread.sleep(600);
+		assertFalse(isAvailable);
+		assertTrue(isReset);
+		isAvailable = false;
+		isReset = false;
+		
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(dataBucket.acquireTokenNonblocking(1024 * 1024, callback));
+		bwController.unregisterBWControllable(context);
+		assertFalse(isAvailable);
+		assertTrue(isReset);
+		
+		channelBandwidth[3] = -1;
+		channelBandwidth[0] = 1024 * 1024; // 1Mbps
+		channelBandwidth[1] = 1024 * 512; // 512Kbps
+		channelBandwidth[2] = 1024 * 256; // 256Kbps
+		channelInitialBurst[0] = channelInitialBurst[1] = channelInitialBurst[2] = 0;
+		bwController.updateBWConfigure(parentContext);
+		context = bwController.registerBWControllable(node);
+		audioBucket = bwController.getAudioBucket(context);
+		videoBucket = bwController.getVideoBucket(context);
+		dataBucket = bwController.getDataBucket(context);
+		assertFalse(audioBucket.acquireToken(1024 * 1024 / 8, 500));
+		assertTrue(audioBucket.acquireToken(1024 * 1024 / 8, 600));
+		
+		Thread.sleep(500);
+		acquired = videoBucket.acquireTokenBestEffort(1024 * 1024 / 8);
+		assertTrue("Acquired " + acquired, acquired > 0 && acquired < 1024 * 1024 / 8);
+		Thread.sleep(500);
+		
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(dataBucket.acquireTokenNonblocking(1024 * 1024 / 8, callback));
+		Thread.sleep(1000);
+		assertFalse(isAvailable);
+		assertFalse(isReset);
+		Thread.sleep(1100);
+		assertTrue(isAvailable);
+		assertFalse(isReset);
+		bwController.unregisterBWControllable(context);
+		assertTrue(isAvailable);
+		assertFalse(isReset);
+		bwController.unregisterBWControllable(parentContext);
+	}
+
+	public void testSingleNodeNoParent() throws Exception {
+		IBWControlService bwController =
+			(IBWControlService) applicationContext.getBean(IBWControlService.KEY);
+		ITokenBucketCallback callback = new TokenBucketCallback();
+		Node node = new Node();
+		node.setParentBWControllable(null);
+		node.setBandwidthConfigure(null);
+		IBWControlContext context = bwController.registerBWControllable(node);
+		ITokenBucket audioBucket = bwController.getAudioBucket(context);
+		ITokenBucket videoBucket = bwController.getVideoBucket(context);
+		ITokenBucket dataBucket = bwController.getDataBucket(context);
+		// no bandwidth configure, all should succeed
+		assertTrue(audioBucket.acquireToken(0, 0));
+		assertTrue(audioBucket.acquireToken(1024, 0));
+		assertTrue(audioBucket.acquireToken(1024 * 1024, 0));
+		assertTrue(videoBucket.acquireToken(0, 0));
+		assertTrue(videoBucket.acquireToken(1024, 0));
+		assertTrue(videoBucket.acquireToken(1024 * 1024, 0));
+		assertTrue(dataBucket.acquireToken(0, 0));
+		assertTrue(dataBucket.acquireToken(1024, 0));
+		assertTrue(dataBucket.acquireToken(1024 * 1024, 0));
+		
+		// use overall bandwidth
+		SimpleBandwidthConfigure config = new SimpleBandwidthConfigure();
+		long[] channelBandwidth = config.getChannelBandwidth();
+		long[] channelInitialBurst = config.getChannelInitialBurst();
+		channelBandwidth[3] = 1024 * 1024; // 1Mbps overall bandwidth
+		channelInitialBurst[3] = 1024 * 1024;
+		node.setBandwidthConfigure(config);
+		bwController.updateBWConfigure(context);
+		// acquire the initial 1024 * 1024 tokens, should succeed
+		assertTrue(audioBucket.acquireToken(1024 * 1024, 0));
+		// acquire 1024 * 1024 tokens w/o wait, should fail
+		assertFalse(audioBucket.acquireToken(1024 * 1024, 0));
+		assertFalse(videoBucket.acquireToken(1024 * 1024, 0));
+		assertFalse(dataBucket.acquireToken(1024 * 1024, 0));
+		// wait 1.1s for 128KB, should succeed
+		assertTrue(audioBucket.acquireToken(1024 * 1024 / 8, 1100));
+		// wait 0.5s for 128KB, should fail
+		assertFalse(videoBucket.acquireToken(1024 * 1024 / 8, 500));
+		// wait another 0.6s for 128KB, should succeed
+		assertTrue(dataBucket.acquireToken(1024 * 1024 / 8, 600));
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(audioBucket.acquireTokenNonblocking(1024 * 1024 / 8, callback));
+		Thread.sleep(500);
+		assertFalse(isAvailable);
+		assertFalse(isReset);
+		Thread.sleep(600);
+		assertTrue(isAvailable);
+		assertFalse(isReset);
+		
+		// wait 500 then best-effort acquire 128KB
+		// the value should be larger than 0 and less than 128KB
+		audioBucket.acquireTokenBestEffort(1024 * 1024);
+		Thread.sleep(500);
+		long acquired = audioBucket.acquireTokenBestEffort(1024 * 1024 / 8);
+		assertTrue("Acquired " + acquired, acquired > 0 && acquired < 1024 * 1024 / 8);
+		
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(videoBucket.acquireTokenNonblocking(1024 * 1024 / 8, callback));
+		bwController.resetBuckets(context);
+		Thread.sleep(500);
+		assertFalse(isAvailable);
+		assertTrue(isReset);
+		Thread.sleep(600);
+		assertFalse(isAvailable);
+		assertTrue(isReset);
+		isAvailable = false;
+		isReset = false;
+		
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(dataBucket.acquireTokenNonblocking(1024 * 1024, callback));
+		bwController.unregisterBWControllable(context);
+		assertFalse(isAvailable);
+		assertTrue(isReset);
+		
+		channelBandwidth[3] = -1;
+		channelBandwidth[0] = 1024 * 1024; // 1Mbps
+		channelBandwidth[1] = 1024 * 512; // 512Kbps
+		channelBandwidth[2] = 1024 * 256; // 256Kbps
+		channelInitialBurst[0] = channelInitialBurst[1] = channelInitialBurst[2] = 0;
+		context = bwController.registerBWControllable(node);
+		audioBucket = bwController.getAudioBucket(context);
+		videoBucket = bwController.getVideoBucket(context);
+		dataBucket = bwController.getDataBucket(context);
+		assertFalse(audioBucket.acquireToken(1024 * 1024 / 8, 500));
+		assertTrue(audioBucket.acquireToken(1024 * 1024 / 8, 600));
+		
+		Thread.sleep(500);
+		acquired = videoBucket.acquireTokenBestEffort(1024 * 1024 / 8);
+		assertTrue("Acquired " + acquired, acquired > 0 && acquired < 1024 * 1024 / 8);
+		Thread.sleep(500);
+		
+		isAvailable = false;
+		isReset = false;
+		// expect false result and wait for callback
+		assertFalse(dataBucket.acquireTokenNonblocking(1024 * 1024 / 8, callback));
+		Thread.sleep(1000);
+		assertFalse(isAvailable);
+		assertFalse(isReset);
+		Thread.sleep(1100);
+		assertTrue(isAvailable);
+		assertFalse(isReset);
+		bwController.unregisterBWControllable(context);
+		assertTrue(isAvailable);
+		assertFalse(isReset);
+	}
+	
+	public void testMultiChildrenNoParent() throws Throwable {
+		final int CLIENT_COUNT = 1000;
+		final int REQUEST_COUNT = 100;
+		
+		boolean[][][] avail = new boolean[CLIENT_COUNT][3][REQUEST_COUNT];
+		TestRunnable[] runnables = new TestRunnable[CLIENT_COUNT];
+		for (int i = 0; i < CLIENT_COUNT; i++) {
+			IBandwidthConfigure c = new SimpleBandwidthConfigure();
+			long[] b = c.getChannelBandwidth();
+			b[3] = 100 * 1024 * 1024;
+			long[] initial = c.getChannelInitialBurst();
+			initial[3] = 0;
+			runnables[i] = new Client(i, null, c, 1024 * 64, avail[i], 1700);
+		}
+		MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(runnables);
+		mttr.runTestRunnables();
+		Thread.sleep(2000);
+		// check all avails
+		for (int i = 0; i < CLIENT_COUNT; i++) {
+			for (int channel = 0; channel < 3; channel++) {
+				for (int j = 0; j < REQUEST_COUNT; j++) {
+					assertTrue("Client No." + i + " on Channel " + channel + " fails on " + j + "th request", avail[i][channel][j]);
+				}
+			}
+		}
+	}
+	
+	public void testMultiChildrenWithParent() throws Throwable {
+		final int CLIENT_COUNT = 50;
+		final int REQUEST_COUNT = 100;
+		Node parent = new Node();
+		parent.setParentBWControllable(null);
+		IBandwidthConfigure config = new SimpleBandwidthConfigure();
+		long[] channelBandwidth = config.getChannelBandwidth();
+		channelBandwidth[3] = 100 * 1024 * 1024 * CLIENT_COUNT;
+		long[] initialBurst = config.getChannelInitialBurst();
+		initialBurst[3] = 100 * 1024 * 1024;
+		parent.setBandwidthConfigure(config);
+		IBWControlService service =
+			(IBWControlService) applicationContext.getBean(IBWControlService.KEY);
+		IBWControlContext context = service.registerBWControllable(parent);
+		
+		boolean[][][] avail = new boolean[CLIENT_COUNT][3][REQUEST_COUNT];
+		TestRunnable[] runnables = new TestRunnable[CLIENT_COUNT];
+		for (int i = 0; i < CLIENT_COUNT; i++) {
+			IBandwidthConfigure c = new SimpleBandwidthConfigure();
+			long[] b = c.getChannelBandwidth();
+			b[3] = 100 * 1024 * 1024;
+			long[] initial = c.getChannelInitialBurst();
+			initial[3] = 0;
+			runnables[i] = new Client(i, parent, c, 1024 * 64, avail[i], 1700);
+		}
+		MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(runnables);
+		mttr.runTestRunnables();
+		Thread.sleep(2000);
+		// check all avails
+		for (int i = 0; i < CLIENT_COUNT; i++) {
+			for (int channel = 0; channel < 3; channel++) {
+				for (int j = 0; j < REQUEST_COUNT; j++) {
+					assertTrue("Client No." + i + " on Channel " + channel + " fails on " + j + "th request", avail[i][channel][j]);
+				}
+			}
+		}
+		service.unregisterBWControllable(context);
+	}
+	
+	class Node implements IBWControllable {
+		IBWControllable parent;
+		IBandwidthConfigure config;
+
+		public void setParentBWControllable(IBWControllable parent) {
+			this.parent = parent;
+		}
+		
+		public IBandwidthConfigure getBandwidthConfigure() {
+			return config;
+		}
+
+		public IBWControllable getParentBWControllable() {
+			return parent;
+		}
+
+		public void setBandwidthConfigure(IBandwidthConfigure config) {
+			this.config = config;
+		}
+		
+	}
+	
+	class TokenBucketCallback implements ITokenBucketCallback {
+		public void available(ITokenBucket bucket, long tokenCount) {
+			isAvailable = true;
+		}
+
+		public void reset(ITokenBucket bucket, long tokenCount) {
+			isReset = true;
+		}
+	}
+	
+	class Client extends TestRunnable {
+		private Node parent;
+		private IBandwidthConfigure config;
+		private boolean[][] availArray;
+		private long tokenCount;
+		private long timeout;
+		private int clientNum;
+		
+		Client(int clientNum, Node parent, IBandwidthConfigure config, long tokenCount, boolean[][] availArray, long timeout) {
+			this.clientNum = clientNum;
+			this.parent = parent;
+			this.config = config;
+			this.tokenCount = tokenCount;
+			this.availArray = availArray;
+			for (int channel = 0; channel < 3; channel++) {
+				for (int i = 0; i < availArray[channel].length; i++) {
+					availArray[channel][i] = false;
+				}
+			}
+			this.timeout = timeout;
+		}
+
+		@Override
+		public void runTest() throws Throwable {
+			long before = System.currentTimeMillis();
+			Node node = new Node();
+			node.setParentBWControllable(parent);
+			node.setBandwidthConfigure(config);
+			IBWControlService service =
+				(IBWControlService) applicationContext.getBean(IBWControlService.KEY);
+			IBWControlContext context = service.registerBWControllable(node);
+			ITokenBucket[] buckets = new ITokenBucket[3];
+			buckets[0] = service.getAudioBucket(context);
+			buckets[1] = service.getVideoBucket(context);
+			buckets[2] = service.getDataBucket(context);
+			Loop: for (int channel = 0; channel < 3; channel++) {
+				for (int i = 0; i < availArray[channel].length; i++) {
+					ITokenBucketCallback callback = new ClientCallback(clientNum, channel, i, availArray);
+					boolean result = buckets[channel].acquireTokenNonblocking(tokenCount, callback);
+					if (result) availArray[channel][i] = true;
+					while (!result && !availArray[channel][i]) {
+						if (timeout >= 0 && System.currentTimeMillis() - before > timeout) {
+							break Loop;
+						}
+						Thread.sleep(10);
+					}
+				}
+			}
+			service.unregisterBWControllable(context);
+		}
+	}
+	
+	class ClientCallback implements ITokenBucketCallback {
+		int clientNum;
+		int channel;
+		int requestNum;
+		boolean[][] availArray;
+		
+		ClientCallback(int clientNum, int channel, int requestNum, boolean[][] availArray) {
+			this.clientNum = clientNum;
+			this.channel = channel;
+			this.requestNum = requestNum;
+			this.availArray = availArray;
+		}
+
+		public void available(ITokenBucket bucket, long tokenCount) {
+			availArray[channel][requestNum] = true;
+		}
+
+		public void reset(ITokenBucket bucket, long tokenCount) {
+			System.err.println("Client " + clientNum + " on Channel " + channel + " reset on " + requestNum + "th request");
+		}
+		
+	}
+}
Index: /java/server/trunk/conf/red5-common.xml
===================================================================
--- /java/server/trunk/conf/red5-common.xml (revision 1715)
+++ /java/server/trunk/conf/red5-common.xml (revision 1743)
@@ -65,18 +65,14 @@
     <bean id="consumerService" class="org.red5.server.stream.ConsumerService"/>
 
-    <!-- Balances flow control -->
-    <!-- 
-    <bean id="FlowControlService" class="org.red5.server.stream.BalancedFlowControlService"
+    <!-- Simple bandwidth control -->
+    <bean id="BWControlService" class="org.red5.server.stream.SimpleBWControlService"
 		 init-method="init">
-		<property name="interval" value="10"/>
-		<property name="defaultCapacity" value="102400"/>
-	</bean> -->
-	
-	<!-- Dummy flow control that does nothing -->
-    <bean id="FlowControlService" class="org.red5.server.stream.DummyFlowControlService"
-		 init-method="init">
-		<property name="interval" value="10"/>
-		<property name="defaultCapacity" value="102400"/>
-	</bean>
+		<property name="interval" value="100"/>
+		<property name="defaultCapacity" value="104857600"/> <!-- 100MB -->
+	</bean>
+		
+	<!-- Dummy bandwidth control that does nothing -->
+	<!-- 
+    <bean id="BWControlService" class="org.red5.server.stream.DummyBWControlService"/> -->
 
     <!-- Scheduling service -->
Index: /java/server/trunk/src/org/red5/server/stream/IBWControlService.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/IBWControlService.java (revision 1743)
+++ /java/server/trunk/src/org/red5/server/stream/IBWControlService.java (revision 1743)
@@ -0,0 +1,104 @@
+package org.red5.server.stream;
+
+/*
+ * RED5 Open Source Flash Server - http://www.osflash.org/red5
+ * 
+ * Copyright (c) 2006-2007 by respective authors (see below). All rights reserved.
+ * 
+ * This library is free software; you can redistribute it and/or modify it under the 
+ * terms of the GNU Lesser General Public License as published by the Free Software 
+ * Foundation; either version 2.1 of the License, or (at your option) any later 
+ * version. 
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY 
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License along 
+ * with this library; if not, write to the Free Software Foundation, Inc., 
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+ */
+
+import org.red5.server.api.IBWControllable;
+
+/**
+ * Bandwidth controller service interface.
+ * <p>
+ * The bandwidth controllable is registered in the bandwidth
+ * controller which provides the three token buckets used for
+ * bandwidth control.
+ * <p>
+ * The bandwidth controller manages the token buckets assigned
+ * to the bandwidth controllable and distributes the tokens
+ * to the buckets in an implementation-specific way. (eg timely
+ * distribute the tokens according to the bandwidth config of
+ * the controllable)
+ * 
+ * @author The Red5 Project (red5 at osflash.org)
+ * @author Steven Gong (steven.gong at gmail.com)
+ */
+public interface IBWControlService {
+	public static final String KEY = "BWControlService";
+
+	/**
+	 * Register a bandwidth controllable. The necessary resources
+	 * will be allocated and assigned to the controllable.
+	 * 
+	 * @param bc The bandwidth controllable.
+	 * @return The registry context. It's used in the subsequent
+	 * calls to controller's method.
+	 */
+	IBWControlContext registerBWControllable(IBWControllable bc);
+	
+	/**
+	 * Unregister the bandwidth controllable. The resources that were
+	 * allocated will be freed.
+	 * @param context The registry context.
+	 */
+	void unregisterBWControllable(IBWControlContext context);
+	
+	/**
+	 * Lookup the registry context according to the controllable.
+	 * @param bc The bandwidth controllable.
+	 * @return The registry context.
+	 */
+	IBWControlContext lookupContext(IBWControllable bc);
+	
+	/**
+	 * Update the bandwidth configuration of a controllable.
+	 * Each time when the controllable changes the bandwidth config
+	 * and wants to make the changes take effect, this method should
+	 * be called.
+	 * 
+	 * @param context The registry context.
+	 */
+	void updateBWConfigure(IBWControlContext context);
+	
+	/**
+	 * Reset all the token buckets for a controllable. All the callback
+	 * will be reset and all blocked threads will be woken up.
+	 * @param context The registry context.
+	 */
+	void resetBuckets(IBWControlContext context);
+	
+	/**
+	 * Return the token bucket for audio channel.
+	 * @param context The registry context.
+	 * @return Token bucket for audio channel.
+	 */
+	ITokenBucket getAudioBucket(IBWControlContext context);
+	
+	/**
+	 * Return the token bucket for video channel.
+	 * @param context The registry context.
+	 * @return Token bucket for video channel.
+	 */
+	ITokenBucket getVideoBucket(IBWControlContext context);
+	
+	/**
+	 * Return the token bucket for data channel.
+	 * @param context The registry context.
+	 * @return Token bucket for data channel.
+	 */
+	ITokenBucket getDataBucket(IBWControlContext context);
+}
Index: /java/server/trunk/src/org/red5/server/stream/SimpleBWControlService.java
===================================================================
--- /java/server/trunk/src/org/red5/server/stream/SimpleBWControlServic

Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.



More information about the Red5commits mailing list