msmith - in flumotion/trunk: .
flumotion/component/consumers/httpstreamer
flumotion-commit at lists.fluendo.com
flumotion-commit at lists.fluendo.com
Fri May 11 18:56:08 CEST 2007
Author: msmith
Date: Fri May 11 18:56:02 2007
New Revision: 4934
Modified:
flumotion/trunk/ChangeLog
flumotion/trunk/flumotion/component/consumers/httpstreamer/http.py
flumotion/trunk/flumotion/component/consumers/httpstreamer/http.xml
flumotion/trunk/flumotion/component/consumers/httpstreamer/resources.py
Log:
* flumotion/component/consumers/httpstreamer/http.py:
* flumotion/component/consumers/httpstreamer/http.xml:
* flumotion/component/consumers/httpstreamer/resources.py:
Implement bandwidth-limit in http streamer.
Implement redirecting clients to a different location when the
server is full (hitting either bandwidth limit or client limit)
Modified: flumotion/trunk/ChangeLog
==============================================================================
--- flumotion/trunk/ChangeLog (original)
+++ flumotion/trunk/ChangeLog Fri May 11 18:56:02 2007
@@ -1,3 +1,12 @@
+2007-05-11 Michael Smith <msmith at fluendo.com>
+
+ * flumotion/component/consumers/httpstreamer/http.py:
+ * flumotion/component/consumers/httpstreamer/http.xml:
+ * flumotion/component/consumers/httpstreamer/resources.py:
+ Implement bandwidth-limit in http streamer.
+ Implement redirecting clients to a different location when the
+ server is full (hitting either bandwidth limit or client limit)
+
2007-05-10 Sebastien Merle <sebastien at fluendo.com>
* flumotion/common/enum.py:
Modified: flumotion/trunk/flumotion/component/consumers/httpstreamer/http.py
==============================================================================
--- flumotion/trunk/flumotion/component/consumers/httpstreamer/http.py (original)
+++ flumotion/trunk/flumotion/component/consumers/httpstreamer/http.py Fri May 11 18:56:02 2007
@@ -50,6 +50,9 @@
T_ = messages.gettexter('flumotion')
__all__ = ['HTTPMedium', 'MultifdSinkStreamer']
+
+
+STATS_POLL_INTERVAL = 10
# FIXME: generalize this class and move it out here ?
class Stats:
@@ -66,6 +69,8 @@
self.load_deltas = [0, 0]
self._load_deltas_period = 10 # seconds
self._load_deltas_ongoing = [time.time(), 0, 0]
+ self._currentBitrate = -1 # not known yet
+ self._lastBytesReceived = -1 # not known yet
# keep track of average clients by tracking last average and its time
self.average_client_number = 0
@@ -123,9 +128,25 @@
self.load_deltas = [(add-oldadd)/diff, (remove-oldremove)/diff]
self._load_deltas_ongoing = [now, add, remove]
+ bytesReceived = self.getBytesReceived()
+ if self._lastBytesReceived >= 0:
+ self._currentBitrate = ((bytesReceived - self._lastBytesReceived) *
+ 8 / STATS_POLL_INTERVAL)
+ self._lastBytesReceived = bytesReceived
+
+ self._currentBitrate = -1 # not known yet
+ self._lastBytesSent = -1 # not known yet
+
self.update_ui_state()
- self._updateCallLaterId = reactor.callLater(10, self._updateStats)
+ self._updateCallLaterId = reactor.callLater(STATS_POLL_INTERVAL,
+ self._updateStats)
+
+ def getCurrentBitrate(self):
+ if self._currentBitrate >= 0:
+ return self._currentBitrate
+ else:
+ return self.getBytesReceived() * 8 / self.getUptime()
def getBytesSent(self):
return self.sink.get_property('bytes-served')
@@ -445,6 +466,13 @@
if properties.has_key('client-limit'):
self.resource.setUserLimit(int(properties['client-limit']))
+ if properties.has_key('bandwidth-limit'):
+ self.resource.setBandwidthLimit(int(properties['bandwidth-limit']))
+
+ if properties.has_key('redirect-on-overflow'):
+ self.resource.setRedirectionOnLimits(
+ properties['redirect-on-overflow'])
+
if properties.has_key('bouncer'):
self.resource.setBouncerName(properties['bouncer'])
Modified: flumotion/trunk/flumotion/component/consumers/httpstreamer/http.xml
==============================================================================
--- flumotion/trunk/flumotion/component/consumers/httpstreamer/http.xml (original)
+++ flumotion/trunk/flumotion/component/consumers/httpstreamer/http.xml Fri May 11 18:56:02 2007
@@ -49,10 +49,14 @@
description="Server's host name to display" />
<property name="domain" type="string"
description="Domain of server for authentication" />
+
<property name="client-limit" type="int"
description="Maximum number of clients allowed" />
<property name="bandwidth-limit" type="int"
- description="Maximum bandwidth usage allowed (not implemented)" />
+ description="Maximum bandwidth usage allowed in bits per second" />
+ <property name="redirect-on-overflow" type="string"
+ description="A URL to redirect clients to if either of the above limits have been reached" />
+
<property name="duration" type="float"
description="How long to keep clients connected for (in seconds) "/>
Modified: flumotion/trunk/flumotion/component/consumers/httpstreamer/resources.py
==============================================================================
--- flumotion/trunk/flumotion/component/consumers/httpstreamer/resources.py (original)
+++ flumotion/trunk/flumotion/component/consumers/httpstreamer/resources.py Fri May 11 18:56:02 2007
@@ -85,6 +85,10 @@
self._requests = {} # request fd -> Request
self.maxclients = self.getMaxAllowedClients(-1)
+ self.maxbandwidth = -1 # not limited by default
+
+ # If set, a URL to redirect a user to when the limits above are reached
+ self._redirectOnFull = None
self.loggers = \
streamer.plugs['flumotion.component.plugs.loggers.Logger']
@@ -150,6 +154,13 @@
# Log what we actually managed to set it to.
self.info('set maxclients to %d' % self.maxclients)
+ def setBandwidthLimit(self, limit):
+ self.maxbandwidth = limit
+ self.info("set maxbandwidth to %d", self.maxbandwidth)
+
+ def setRedirectionOnLimits(self, url):
+ self._redirectOnFull = url
+
# FIXME: rename to writeHeaders
"""
Write out the HTTP headers for the incoming HTTP request.
@@ -249,8 +260,14 @@
else:
return softmax - self.__reserve_fds__
- def reachedMaxClients(self):
- return len(self._requests) >= self.maxclients and self.maxclients >= 0
+ def reachedServerLimits(self):
+ if self.maxclients >= 0 and len(self._requests) >= self.maxclients:
+ return True
+ elif self.maxbandwidth >= 0:
+ if (len(self._requests) * self.streamer.getCurrentBitrate() >=
+ self.maxbandwidth):
+ return True
+ return False
def _addClient(self, request):
"""
@@ -338,8 +355,8 @@
if not self.isReady():
return self._handleNotReady(request)
- elif self.reachedMaxClients():
- return self._handleMaxClients(request)
+ elif self.reachedServerLimits():
+ return self._handleServerFull(request)
self.debug('_render(): asked for (possible) authentication')
d = self.startAuthentication(request)
@@ -358,14 +375,20 @@
self.debug('Not sending data, it\'s not ready')
return server.NOT_DONE_YET
- def _handleMaxClients(self, request):
- self.debug('Refusing clients, client limit %d reached' %
- self.maxclients)
+ def _handleServerFull(self, request):
+ if self._redirectOnFull:
+ self.debug("Redirecting client, client limit %d reached",
+ self.maxclients)
+ error_code = http.FOUND
+ request.setHeader('location', self._redirectOnFull)
+ else:
+ self.debug('Refusing clients, client limit %d reached' %
+ self.maxclients)
+ error_code = http.SERVICE_UNAVAILABLE
request.setHeader('content-type', 'text/html')
- request.setHeader('server', HTTP_VERSION)
- error_code = http.SERVICE_UNAVAILABLE
+ request.setHeader('server', HTTP_VERSION)
request.setResponseCode(error_code)
return ERROR_TEMPLATE % {'code': error_code,
More information about the flumotion-commit
mailing list