download throttle

This commit is contained in:
David Rose 2002-10-17 06:17:41 +00:00
parent f6f16e60d3
commit 034291f780
3 changed files with 139 additions and 0 deletions

View File

@ -166,6 +166,96 @@ get_persistent_connection() const {
return _persistent_connection;
}
////////////////////////////////////////////////////////////////////
// Function: HTTPChannel::set_download_throttle
// Access: Published
// Description: Specifies whether nonblocking downloads (via
// download_to_file() or download_to_ram()) will be
// limited so as not to use all available bandwidth.
//
// If this is true, when a download has been started on
// this channel it will be invoked no more frequently
// than get_max_updates_per_second(), and the total
// bandwidth used by the download will be no more than
// get_max_bytes_per_second(). If this is false,
// downloads will proceed as fast as the server can send
// the data.
//
// This only has effect on the nonblocking I/O methods
// like request_document(), etc. The blocking methods
// like get_document() always use as much CPU and
// bandwidth as they can get.
////////////////////////////////////////////////////////////////////
INLINE void HTTPChannel::
set_download_throttle(bool download_throttle) {
_download_throttle = download_throttle;
}
////////////////////////////////////////////////////////////////////
// Function: HTTPChannel::get_download_throttle
// Access: Published
// Description: Returns whether the nonblocking downloads will be
// bandwidth-limited. See set_download_throttle().
////////////////////////////////////////////////////////////////////
INLINE bool HTTPChannel::
get_download_throttle() const {
return _download_throttle;
}
////////////////////////////////////////////////////////////////////
// Function: HTTPChannel::set_max_bytes_per_second
// Access: Published
// Description: When bandwidth throttling is in effect (see
// set_download_throttle()), this specifies the maximum
// number of bytes per second that may be consumed by
// this channel.
////////////////////////////////////////////////////////////////////
INLINE void HTTPChannel::
set_max_bytes_per_second(double max_bytes_per_second) {
_max_bytes_per_second = max_bytes_per_second;
_bytes_per_update = int(_max_bytes_per_second * _seconds_per_update);
}
////////////////////////////////////////////////////////////////////
// Function: HTTPChannel::get_max_bytes_per_second
// Access: Published
// Description: Returns the maximum number of bytes per second that
// may be consumed by this channel when
// get_download_throttle() is true.
////////////////////////////////////////////////////////////////////
INLINE double HTTPChannel::
get_max_bytes_per_second() const {
return _max_bytes_per_second;
}
////////////////////////////////////////////////////////////////////
// Function: HTTPChannel::set_max_updates_per_second
// Access: Published
// Description: When bandwidth throttling is in effect (see
// set_download_throttle()), this specifies the maximum
// number of times per second that run() will attempt to
// do any downloading at all.
////////////////////////////////////////////////////////////////////
INLINE void HTTPChannel::
set_max_updates_per_second(double max_updates_per_second) {
nassertv(max_updates_per_second != 0.0f);
_max_updates_per_second = max_updates_per_second;
_seconds_per_update = 1.0f / _max_updates_per_second;
_bytes_per_update = int(_max_bytes_per_second * _seconds_per_update);
}
////////////////////////////////////////////////////////////////////
// Function: HTTPChannel::get_max_updates_per_second
// Access: Published
// Description: Returns the maximum number of times per second that
// run() will do anything at all, when
// get_download_throttle() is true.
////////////////////////////////////////////////////////////////////
INLINE double HTTPChannel::
get_max_updates_per_second() const {
return _max_updates_per_second;
}
////////////////////////////////////////////////////////////////////
// Function: HTTPChannel::get_file_size
// Access: Published

View File

@ -21,6 +21,8 @@
#include "bioStream.h"
#include "chunkedStream.h"
#include "identityStream.h"
#include "config_downloader.h"
#include "clockObject.h"
#include "buffer.h" // for Ramfile
#ifdef HAVE_SSL
@ -48,6 +50,11 @@ HTTPChannel(HTTPClient *client) :
_client(client)
{
_persistent_connection = false;
_download_throttle = false;
_max_bytes_per_second = downloader_byte_rate;
_seconds_per_update = downloader_frequency;
_max_updates_per_second = 1.0f / _seconds_per_update;
_bytes_per_update = int(_max_bytes_per_second * _seconds_per_update);
_nonblocking = false;
_read_index = 0;
_file_size = 0;
@ -63,6 +70,8 @@ HTTPChannel(HTTPClient *client) :
_proxy_tunnel = false;
_body_stream = NULL;
_sbio = NULL;
_last_status_code = 0;
_last_run_time = 0.0f;
_download_to_ramfile = NULL;
}
@ -201,6 +210,15 @@ run() {
}
if (_started_download) {
if (_nonblocking && _download_throttle) {
double now = ClockObject::get_global_clock()->get_real_time();
double elapsed = now - _last_run_time;
_last_run_time = now;
if (elapsed < _seconds_per_update) {
// Come back later.
return true;
}
}
switch (_download_dest) {
case DD_none:
return false; // We're done.
@ -1102,9 +1120,17 @@ bool HTTPChannel::
run_download_to_file() {
nassertr(_body_stream != (ISocketStream *)NULL, false);
bool do_throttle = _nonblocking && _download_throttle;
int count = 0;
int ch = _body_stream->get();
while (!_body_stream->eof() && !_body_stream->fail()) {
_download_to_file.put(ch);
if (do_throttle && ++count > _bytes_per_update) {
// That's enough for now.
return true;
}
ch = _body_stream->get();
}
@ -1137,9 +1163,17 @@ run_download_to_ram() {
nassertr(_body_stream != (ISocketStream *)NULL, false);
nassertr(_download_to_ramfile != (Ramfile *)NULL, false);
bool do_throttle = _nonblocking && _download_throttle;
int count = 0;
int ch = _body_stream->get();
while (!_body_stream->eof() && !_body_stream->fail()) {
_download_to_ramfile->_data += (char)ch;
if (do_throttle && ++count > _bytes_per_update) {
// That's enough for now.
return true;
}
ch = _body_stream->get();
}

View File

@ -86,6 +86,15 @@ PUBLISHED:
INLINE void set_persistent_connection(bool persistent_connection);
INLINE bool get_persistent_connection() const;
INLINE void set_download_throttle(bool download_throttle);
INLINE bool get_download_throttle() const;
INLINE void set_max_bytes_per_second(double max_bytes_per_second);
INLINE double get_max_bytes_per_second() const;
INLINE void set_max_updates_per_second(double max_updates_per_second);
INLINE double get_max_updates_per_second() const;
INLINE size_t get_file_size() const;
void write_headers(ostream &out) const;
@ -165,6 +174,11 @@ private:
PT(BioPtr) _bio;
PT(BioStreamPtr) _source;
bool _persistent_connection;
bool _download_throttle;
double _max_bytes_per_second;
double _max_updates_per_second;
double _seconds_per_update;
int _bytes_per_update;
bool _nonblocking;
URLSpec _url;
@ -235,6 +249,7 @@ private:
BIO *_sbio;
pset<URLSpec> _redirect_trail;
int _last_status_code;
double _last_run_time;
typedef pmap<string, string> Tokens;
typedef pmap<string, Tokens> AuthenticationSchemes;