auto upload slots. opens up more slots if upload rate is not met. On by default

This commit is contained in:
Arvid Norberg 2008-01-13 11:18:18 +00:00
parent 72eee8838c
commit 5d196ed555
8 changed files with 79 additions and 4 deletions

View File

@ -1,3 +1,8 @@
* Auto Upload slots. Automtically opens up more slots if
upload limit is not met.
* Improved NAT-PMP support by querying the default gateway (no
linux support yet)
* Improved UPnP support by ignoring routers not on the clients subnet.
release 0.13 release 0.13

View File

@ -607,6 +607,8 @@ struct session_status
size_type total_payload_upload; size_type total_payload_upload;
int num_peers; int num_peers;
int num_unchoked;
int allowed_upload_slots;
int dht_nodes; int dht_nodes;
int dht_cache_nodes; int dht_cache_nodes;
@ -628,6 +630,8 @@ incoming connections that still hasn't sent their handshake or outgoing connecti
that still hasn't completed the TCP connection. This number may be slightly higher that still hasn't completed the TCP connection. This number may be slightly higher
than the sum of all peers of all torrents because the incoming connections may not than the sum of all peers of all torrents because the incoming connections may not
be assigned a torrent yet.</p> be assigned a torrent yet.</p>
<p><tt class="docutils literal"><span class="pre">num_unchoked</span></tt> is the current number of unchoked peers.
<tt class="docutils literal"><span class="pre">allowed_upload_slots</span></tt> is the current allowed number of unchoked peers.</p>
<p><tt class="docutils literal"><span class="pre">dht_nodes</span></tt>, <tt class="docutils literal"><span class="pre">dht_cache_nodes</span></tt> and <tt class="docutils literal"><span class="pre">dht_torrents</span></tt> are only available when <p><tt class="docutils literal"><span class="pre">dht_nodes</span></tt>, <tt class="docutils literal"><span class="pre">dht_cache_nodes</span></tt> and <tt class="docutils literal"><span class="pre">dht_torrents</span></tt> are only available when
built with DHT support. They are all set to 0 if the DHT isn't running. When built with DHT support. They are all set to 0 if the DHT isn't running. When
the DHT is running, <tt class="docutils literal"><span class="pre">dht_nodes</span></tt> is set to the number of nodes in the routing the DHT is running, <tt class="docutils literal"><span class="pre">dht_nodes</span></tt> is set to the number of nodes in the routing
@ -2499,6 +2503,7 @@ struct session_settings
bool free_torrent_hashes; bool free_torrent_hashes;
bool upnp_ignore_nonrouters; bool upnp_ignore_nonrouters;
int send_buffer_watermark; int send_buffer_watermark;
bool auto_upload_slots;
}; };
</pre> </pre>
<p><tt class="docutils literal"><span class="pre">user_agent</span></tt> this is the client identification to the tracker. <p><tt class="docutils literal"><span class="pre">user_agent</span></tt> this is the client identification to the tracker.
@ -2615,6 +2620,12 @@ if the send buffer has fewer bytes than this, we'll read another 16kB block
onto it. If set too small, upload rate capacity will suffer. If set too high, onto it. If set too small, upload rate capacity will suffer. If set too high,
memory will be wasted. The actual watermark may be lower than this in case memory will be wasted. The actual watermark may be lower than this in case
the upload rate is low, this is the upper limit.</p> the upload rate is low, this is the upper limit.</p>
<p><tt class="docutils literal"><span class="pre">auto_upload_slots</span></tt> defaults to true. When true, if there is a global upload
limit set and the current upload rate is less than 90% of that, another upload
slot is opened. If the upload rate has been saturated for an extended period
of time, on upload slot is closed. The number of upload slots will never be
less than what has been set by <tt class="docutils literal"><span class="pre">session::set_max_uploads()</span></tt>. To query the
current number of upload slots, see <tt class="docutils literal"><span class="pre">session_status::allowed_upload_slots</span></tt>.</p>
</div> </div>
<div class="section"> <div class="section">
<h1><a id="pe-settings" name="pe-settings">pe_settings</a></h1> <h1><a id="pe-settings" name="pe-settings">pe_settings</a></h1>

View File

@ -447,6 +447,8 @@ struct has the following members::
size_type total_payload_upload; size_type total_payload_upload;
int num_peers; int num_peers;
int num_unchoked;
int allowed_upload_slots;
int dht_nodes; int dht_nodes;
int dht_cache_nodes; int dht_cache_nodes;
@ -472,6 +474,9 @@ that still hasn't completed the TCP connection. This number may be slightly high
than the sum of all peers of all torrents because the incoming connections may not than the sum of all peers of all torrents because the incoming connections may not
be assigned a torrent yet. be assigned a torrent yet.
``num_unchoked`` is the current number of unchoked peers.
``allowed_upload_slots`` is the current allowed number of unchoked peers.
``dht_nodes``, ``dht_cache_nodes`` and ``dht_torrents`` are only available when ``dht_nodes``, ``dht_cache_nodes`` and ``dht_torrents`` are only available when
built with DHT support. They are all set to 0 if the DHT isn't running. When built with DHT support. They are all set to 0 if the DHT isn't running. When
the DHT is running, ``dht_nodes`` is set to the number of nodes in the routing the DHT is running, ``dht_nodes`` is set to the number of nodes in the routing
@ -2487,6 +2492,7 @@ that will be sent to the tracker. The user-agent is a good way to identify your
bool free_torrent_hashes; bool free_torrent_hashes;
bool upnp_ignore_nonrouters; bool upnp_ignore_nonrouters;
int send_buffer_watermark; int send_buffer_watermark;
bool auto_upload_slots;
}; };
``user_agent`` this is the client identification to the tracker. ``user_agent`` this is the client identification to the tracker.
@ -2630,6 +2636,13 @@ onto it. If set too small, upload rate capacity will suffer. If set too high,
memory will be wasted. The actual watermark may be lower than this in case memory will be wasted. The actual watermark may be lower than this in case
the upload rate is low, this is the upper limit. the upload rate is low, this is the upper limit.
``auto_upload_slots`` defaults to true. When true, if there is a global upload
limit set and the current upload rate is less than 90% of that, another upload
slot is opened. If the upload rate has been saturated for an extended period
of time, on upload slot is closed. The number of upload slots will never be
less than what has been set by ``session::set_max_uploads()``. To query the
current number of upload slots, see ``session_status::allowed_upload_slots``.
pe_settings pe_settings
=========== ===========

View File

@ -1184,10 +1184,12 @@ int main(int ac, char* av[])
} }
out << "conns: " << sess_stat.num_peers << " down: " << esc("32") << add_suffix(sess_stat.download_rate) << "/s" << esc("0") out << "==== conns: " << sess_stat.num_peers << " down: " << esc("32") << add_suffix(sess_stat.download_rate) << "/s" << esc("0")
<< " (" << esc("32") << add_suffix(sess_stat.total_download) << esc("0") << ") " << " (" << esc("32") << add_suffix(sess_stat.total_download) << esc("0") << ") "
" up: " << esc("31") << add_suffix(sess_stat.upload_rate) << "/s " << esc("0") " up: " << esc("31") << add_suffix(sess_stat.upload_rate) << "/s " << esc("0")
<< " (" << esc("31") << add_suffix(sess_stat.total_upload) << esc("0") << ")" << std::endl; << " (" << esc("31") << add_suffix(sess_stat.total_upload) << esc("0") << ")"
" unchoked: " << sess_stat.num_unchoked << " / " << sess_stat.allowed_upload_slots
<< " ====" << std::endl;
if (print_log) if (print_log)
{ {

View File

@ -503,7 +503,14 @@ namespace libtorrent
// should exit // should exit
volatile bool m_abort; volatile bool m_abort;
// the max number of unchoked peers as set by the user
int m_max_uploads; int m_max_uploads;
// the number of unchoked peers as set by the auto-unchoker
// this should always be >= m_max_uploads
int m_allowed_upload_slots;
// the max number of connections, as set by the user
int m_max_connections; int m_max_connections;
// the number of unchoked peers // the number of unchoked peers

View File

@ -119,6 +119,7 @@ namespace libtorrent
, free_torrent_hashes(true) , free_torrent_hashes(true)
, upnp_ignore_nonrouters(true) , upnp_ignore_nonrouters(true)
, send_buffer_watermark(80 * 1024) , send_buffer_watermark(80 * 1024)
, auto_upload_slots(true)
{} {}
// this is the user agent that will be sent to the tracker // this is the user agent that will be sent to the tracker
@ -307,6 +308,15 @@ namespace libtorrent
// The actual watermark may be lower than this in case // The actual watermark may be lower than this in case
// the upload rate is low, this is the upper limit. // the upload rate is low, this is the upper limit.
int send_buffer_watermark; int send_buffer_watermark;
// if auto_upload_slots is true, and a global upload
// limit is set and the upload rate is less than 90%
// of the upload limit, on new slot is opened up. If
// the upload rate is >= upload limit for an extended
// period of time, one upload slot is closed. The
// upload slots are never automatically decreased below
// the manual settings, through max_uploads.
bool auto_upload_slots;
}; };
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT

View File

@ -54,6 +54,8 @@ namespace libtorrent
size_type total_payload_upload; size_type total_payload_upload;
int num_peers; int num_peers;
int num_unchoked;
int allowed_upload_slots;
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
int dht_nodes; int dht_nodes;

View File

@ -564,6 +564,7 @@ namespace detail
, m_listen_interface(address::from_string(listen_interface), listen_port_range.first) , m_listen_interface(address::from_string(listen_interface), listen_port_range.first)
, m_abort(false) , m_abort(false)
, m_max_uploads(8) , m_max_uploads(8)
, m_allowed_upload_slots(8)
, m_max_connections(200) , m_max_connections(200)
, m_num_unchoked(0) , m_num_unchoked(0)
, m_unchoke_time_scaler(0) , m_unchoke_time_scaler(0)
@ -808,6 +809,7 @@ namespace detail
TORRENT_ASSERT(s.unchoke_interval >= 5); TORRENT_ASSERT(s.unchoke_interval >= 5);
m_settings = s; m_settings = s;
m_files.resize(m_settings.file_pool_size); m_files.resize(m_settings.file_pool_size);
if (!s.auto_upload_slots) m_allowed_upload_slots = m_max_uploads;
// replace all occurances of '\n' with ' '. // replace all occurances of '\n' with ' '.
std::string::iterator i = m_settings.user_agent.begin(); std::string::iterator i = m_settings.user_agent.begin();
while ((i = std::find(i, m_settings.user_agent.end(), '\n')) while ((i = std::find(i, m_settings.user_agent.end(), '\n'))
@ -1420,8 +1422,25 @@ namespace detail
, bind(&stat::download_payload_rate, bind(&peer_connection::statistics, _1)) , bind(&stat::download_payload_rate, bind(&peer_connection::statistics, _1))
> bind(&stat::download_payload_rate, bind(&peer_connection::statistics, _2))); > bind(&stat::download_payload_rate, bind(&peer_connection::statistics, _2)));
// auto unchoke
int upload_limit = m_bandwidth_manager[peer_connection::upload_channel]->throttle();
if (m_settings.auto_upload_slots && upload_limit != bandwidth_limit::inf)
{
// if our current upload rate is less than 90% of our
if (m_stat.upload_rate() < upload_limit * 0.9f
&& m_allowed_upload_slots < m_num_unchoked + 2)
{
++m_allowed_upload_slots;
}
else if (m_stat.upload_rate() >= upload_limit
&& m_allowed_upload_slots > m_max_uploads)
{
--m_allowed_upload_slots;
}
}
// reserve one upload slot for optimistic unchokes // reserve one upload slot for optimistic unchokes
int unchoke_set_size = m_max_uploads - 1; int unchoke_set_size = m_allowed_upload_slots - 1;
m_num_unchoked = 0; m_num_unchoked = 0;
// go through all the peers and unchoke the first ones and choke // go through all the peers and unchoke the first ones and choke
@ -2007,8 +2026,12 @@ namespace detail
// INVARIANT_CHECK; // INVARIANT_CHECK;
session_status s; session_status s;
s.has_incoming_connections = m_incoming_connection;
s.num_peers = (int)m_connections.size(); s.num_peers = (int)m_connections.size();
s.num_unchoked = m_num_unchoked;
s.allowed_upload_slots = m_allowed_upload_slots;
s.has_incoming_connections = m_incoming_connection;
s.download_rate = m_stat.download_rate(); s.download_rate = m_stat.download_rate();
s.upload_rate = m_stat.upload_rate(); s.upload_rate = m_stat.upload_rate();
@ -2213,6 +2236,7 @@ namespace detail
if (limit <= 0) limit = (std::numeric_limits<int>::max)(); if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_max_uploads = limit; m_max_uploads = limit;
if (m_allowed_upload_slots < limit) m_allowed_upload_slots = limit;
} }
void session_impl::set_max_connections(int limit) void session_impl::set_max_connections(int limit)
@ -2422,6 +2446,7 @@ namespace detail
{ {
TORRENT_ASSERT(m_max_connections > 0); TORRENT_ASSERT(m_max_connections > 0);
TORRENT_ASSERT(m_max_uploads > 0); TORRENT_ASSERT(m_max_uploads > 0);
TORRENT_ASSERT(m_allowed_upload_slots >= m_max_uploads);
int unchokes = 0; int unchokes = 0;
int num_optimistic = 0; int num_optimistic = 0;
for (connection_map::const_iterator i = m_connections.begin(); for (connection_map::const_iterator i = m_connections.begin();