improved LSD performance and made the interval configurable
This commit is contained in:
parent
7b0555ae45
commit
088f4bf700
|
@ -100,6 +100,7 @@
|
|||
* fixed magnet link issue when using resume data
|
||||
* support disk I/O priority settings
|
||||
* added info_hash to torrent_deleted_alert
|
||||
* improved LSD performance and made the interval configurable
|
||||
|
||||
release 0.14.9
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ void bind_session_settings()
|
|||
.def_readwrite("max_suggest_pieces", &session_settings::max_suggest_pieces)
|
||||
.def_readwrite("drop_skipped_requests", &session_settings::drop_skipped_requests)
|
||||
.def_readwrite("low_prio_disk", &session_settings::low_prio_disk)
|
||||
.def_readwrite("local_service_announce_interval", &session_settings::local_service_announce_interval)
|
||||
.def_readwrite("volatile_read_cache", &session_settings::volatile_read_cache)
|
||||
.def_readwrite("guided_read_cache", &guided_read_cache)
|
||||
;
|
||||
|
|
|
@ -3721,6 +3721,7 @@ session_settings
|
|||
bool drop_skipped_requests;
|
||||
|
||||
bool low_prio_disk;
|
||||
int local_service_announce_interval;
|
||||
bool volatile_read_cache;
|
||||
bool guided_read_cache;
|
||||
bool default_min_cache_age;
|
||||
|
@ -4194,6 +4195,11 @@ overall responsiveness of the system while downloading in the
|
|||
background. For high-performance server setups, this might not
|
||||
be desirable.
|
||||
|
||||
``local_service_announce_interval`` is the time between local
|
||||
network announces for a torrent. By default, when local service
|
||||
discovery is enabled a torrent announces itself every 5 minutes.
|
||||
This interval is specified in seconds.
|
||||
|
||||
``volatile_read_cache``, if this is set to true, read cache blocks
|
||||
that are hit by peer read requests are removed from the disk cache
|
||||
to free up more space. This is useful if you don't expect the disk
|
||||
|
|
|
@ -205,6 +205,8 @@ namespace libtorrent
|
|||
|
||||
void on_port_map_log(char const* msg, int map_transport);
|
||||
|
||||
void on_lsd_announce(error_code const& e);
|
||||
|
||||
// called when a port mapping is successful, or a router returns
|
||||
// a failure to map a port
|
||||
void on_port_mapping(int mapping, int port, error_code const& ec
|
||||
|
@ -709,10 +711,20 @@ namespace libtorrent
|
|||
// the timer used to fire the tick
|
||||
deadline_timer m_timer;
|
||||
|
||||
// torrents are announced on the local network in a
|
||||
// round-robin fashion. All torrents are cycled through
|
||||
// within the LSD announce interval (which defaults to
|
||||
// 5 minutes)
|
||||
torrent_map::iterator m_next_lsd_torrent;
|
||||
|
||||
// this announce timer is used
|
||||
// by Local service discovery
|
||||
deadline_timer m_lsd_announce_timer;
|
||||
|
||||
// the index of the torrent that will be offered to
|
||||
// connect to a peer next time on_tick is called.
|
||||
// This implements a round robin.
|
||||
int m_next_connect_torrent;
|
||||
torrent_map::iterator m_next_connect_torrent;
|
||||
#ifdef TORRENT_DEBUG
|
||||
void check_invariant() const;
|
||||
#endif
|
||||
|
|
|
@ -186,6 +186,7 @@ namespace libtorrent
|
|||
, max_suggest_pieces(10)
|
||||
, drop_skipped_requests(false)
|
||||
, low_prio_disk(true)
|
||||
, local_service_announce_interval(5 * 60)
|
||||
, volatile_read_cache(false)
|
||||
, guided_read_cache(true)
|
||||
, default_cache_min_age(1)
|
||||
|
@ -689,6 +690,10 @@ namespace libtorrent
|
|||
// in the background
|
||||
bool low_prio_disk;
|
||||
|
||||
// number of seconds between local service announces for
|
||||
// torrents. Defaults to 5 minutes
|
||||
int local_service_announce_interval;
|
||||
|
||||
// if this is set to true, any block read from the
|
||||
// disk cache will be dropped from the cache immediately
|
||||
// following. This may be useful if the block is not
|
||||
|
|
|
@ -723,6 +723,10 @@ namespace libtorrent
|
|||
|
||||
bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int piece);
|
||||
|
||||
// this is called once periodically for torrents
|
||||
// that are not private
|
||||
void lsd_announce();
|
||||
|
||||
private:
|
||||
|
||||
void on_files_deleted(int ret, disk_io_job const& j);
|
||||
|
@ -838,10 +842,12 @@ namespace libtorrent
|
|||
// used to resolve the names of web seeds
|
||||
mutable tcp::resolver m_host_resolver;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// this announce timer is used both
|
||||
// by Local service discovery and
|
||||
// by the DHT.
|
||||
deadline_timer m_lsd_announce_timer;
|
||||
deadline_timer m_dht_announce_timer;
|
||||
#endif
|
||||
|
||||
// used for tracker announces
|
||||
deadline_timer m_tracker_timer;
|
||||
|
@ -853,18 +859,14 @@ namespace libtorrent
|
|||
|
||||
void on_tracker_announce();
|
||||
|
||||
static void on_lsd_announce_disp(boost::weak_ptr<torrent> p
|
||||
, error_code const& e);
|
||||
|
||||
// this is called once every 5 minutes for torrents
|
||||
// that are not private
|
||||
void on_lsd_announce();
|
||||
void dht_announce();
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
||||
, std::vector<tcp::endpoint> const& peers);
|
||||
void on_dht_announce_response(std::vector<tcp::endpoint> const& peers);
|
||||
bool should_announce_dht() const;
|
||||
void on_dht_announce(error_code const& e);
|
||||
|
||||
// the time when the DHT was last announced of our
|
||||
// presence on this torrent
|
||||
|
|
|
@ -285,6 +285,7 @@ namespace aux {
|
|||
TORRENT_SETTING(integer, max_suggest_pieces)
|
||||
TORRENT_SETTING(boolean, drop_skipped_requests)
|
||||
TORRENT_SETTING(boolean, low_prio_disk)
|
||||
TORRENT_SETTING(boolean, local_service_announce_interval)
|
||||
};
|
||||
|
||||
#undef TORRENT_SETTING
|
||||
|
@ -443,7 +444,7 @@ namespace aux {
|
|||
, m_half_open)
|
||||
#endif
|
||||
, m_timer(m_io_service)
|
||||
, m_next_connect_torrent(0)
|
||||
, m_lsd_announce_timer(m_io_service)
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||
, m_logpath(logpath)
|
||||
#endif
|
||||
|
@ -454,6 +455,9 @@ namespace aux {
|
|||
, m_total_failed_bytes(0)
|
||||
, m_total_redundant_bytes(0)
|
||||
{
|
||||
m_next_lsd_torrent = m_torrents.begin();
|
||||
m_next_connect_torrent = m_torrents.begin();
|
||||
|
||||
TORRENT_ASSERT(listen_interface);
|
||||
error_code ec;
|
||||
m_listen_interface = tcp::endpoint(address::from_string(listen_interface, ec), listen_port_range.first);
|
||||
|
@ -590,6 +594,12 @@ namespace aux {
|
|||
m_timer.expires_from_now(milliseconds(100), ec);
|
||||
m_timer.async_wait(bind(&session_impl::on_tick, this, _1));
|
||||
|
||||
int delay = (std::max)(m_settings.local_service_announce_interval
|
||||
/ (std::max)(int(m_torrents.size()), 1), 1);
|
||||
m_lsd_announce_timer.expires_from_now(seconds(delay), ec);
|
||||
m_lsd_announce_timer.async_wait(
|
||||
bind(&session_impl::on_lsd_announce, this, _1));
|
||||
|
||||
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
|
||||
}
|
||||
|
||||
|
@ -900,6 +910,7 @@ namespace aux {
|
|||
m_dht_socket.close();
|
||||
#endif
|
||||
m_timer.cancel(ec);
|
||||
m_lsd_announce_timer.cancel(ec);
|
||||
|
||||
// close the listen sockets
|
||||
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
|
||||
|
@ -1963,16 +1974,14 @@ namespace aux {
|
|||
if (num_downloads > 0)
|
||||
average_peers = num_downloads_peers / num_downloads;
|
||||
|
||||
torrent_map::iterator i = m_torrents.begin();
|
||||
if (m_next_connect_torrent < int(m_torrents.size()))
|
||||
std::advance(i, m_next_connect_torrent);
|
||||
else
|
||||
m_next_connect_torrent = 0;
|
||||
if (m_next_connect_torrent == m_torrents.end())
|
||||
m_next_connect_torrent = m_torrents.begin();
|
||||
|
||||
int steps_since_last_connect = 0;
|
||||
int num_torrents = int(m_torrents.size());
|
||||
for (;;)
|
||||
{
|
||||
torrent& t = *i->second;
|
||||
torrent& t = *m_next_connect_torrent->second;
|
||||
if (t.want_more_peers())
|
||||
{
|
||||
int connect_points = 100;
|
||||
|
@ -2012,15 +2021,12 @@ namespace aux {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
++m_next_connect_torrent;
|
||||
++steps_since_last_connect;
|
||||
++i;
|
||||
if (i == m_torrents.end())
|
||||
{
|
||||
TORRENT_ASSERT(m_next_connect_torrent == num_torrents);
|
||||
i = m_torrents.begin();
|
||||
m_next_connect_torrent = 0;
|
||||
}
|
||||
if (m_next_connect_torrent == m_torrents.end())
|
||||
m_next_connect_torrent = m_torrents.begin();
|
||||
|
||||
// if we have gone two whole loops without
|
||||
// handing out a single connection, break
|
||||
if (steps_since_last_connect > num_torrents * 2) break;
|
||||
|
@ -2111,6 +2117,27 @@ namespace aux {
|
|||
// m_peer_pool.release_memory();
|
||||
}
|
||||
|
||||
void session_impl::on_lsd_announce(error_code const& e)
|
||||
{
|
||||
if (e) return;
|
||||
|
||||
mutex::scoped_lock l(m_mutex);
|
||||
|
||||
// announce on local network every 5 minutes
|
||||
int delay = (std::max)(m_settings.local_service_announce_interval
|
||||
/ (std::max)(int(m_torrents.size()), 1), 1);
|
||||
error_code ec;
|
||||
m_lsd_announce_timer.expires_from_now(seconds(delay), ec);
|
||||
m_lsd_announce_timer.async_wait(
|
||||
bind(&session_impl::on_lsd_announce, this, _1));
|
||||
|
||||
if (m_next_lsd_torrent == m_torrents.end()) return;
|
||||
m_next_lsd_torrent->second->lsd_announce();
|
||||
++m_next_lsd_torrent;
|
||||
if (m_next_lsd_torrent == m_torrents.end())
|
||||
m_next_lsd_torrent = m_torrents.begin();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool is_active(torrent* t, session_settings const& s)
|
||||
|
@ -2729,8 +2756,19 @@ namespace aux {
|
|||
#ifdef TORRENT_DEBUG
|
||||
sha1_hash i_hash = t.torrent_file().info_hash();
|
||||
#endif
|
||||
if (i == m_next_lsd_torrent)
|
||||
++m_next_lsd_torrent;
|
||||
if (i == m_next_connect_torrent)
|
||||
++m_next_connect_torrent;
|
||||
|
||||
t.set_queue_position(-1);
|
||||
m_torrents.erase(i);
|
||||
|
||||
if (m_next_lsd_torrent == m_torrents.end())
|
||||
m_next_lsd_torrent = m_torrents.begin();
|
||||
if (m_next_connect_torrent == m_torrents.end())
|
||||
m_next_connect_torrent = m_torrents.begin();
|
||||
|
||||
std::list<boost::shared_ptr<torrent> >::iterator k
|
||||
= std::find(m_queued_for_checking.begin(), m_queued_for_checking.end(), tptr);
|
||||
if (k != m_queued_for_checking.end()) m_queued_for_checking.erase(k);
|
||||
|
|
|
@ -214,7 +214,9 @@ namespace libtorrent
|
|||
, m_torrent_file(p.ti ? p.ti : new torrent_info(p.info_hash))
|
||||
, m_storage(0)
|
||||
, m_host_resolver(ses.m_io_service)
|
||||
, m_lsd_announce_timer(ses.m_io_service)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
, m_dht_announce_timer(ses.m_io_service)
|
||||
#endif
|
||||
, m_tracker_timer(ses.m_io_service)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
, m_last_dht_announce(time_now() - minutes(15))
|
||||
|
@ -368,10 +370,9 @@ namespace libtorrent
|
|||
// DHT announces are done on the local service
|
||||
// discovery timer. Trigger it.
|
||||
error_code ec;
|
||||
boost::weak_ptr<torrent> self(shared_from_this());
|
||||
m_lsd_announce_timer.expires_from_now(seconds(1), ec);
|
||||
m_lsd_announce_timer.async_wait(
|
||||
bind(&torrent::on_lsd_announce_disp, self, _1));
|
||||
m_dht_announce_timer.expires_from_now(seconds(1), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
bind(&torrent::on_dht_announce, shared_from_this(), _1));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1175,30 +1176,14 @@ namespace libtorrent
|
|||
announce_with_tracker();
|
||||
}
|
||||
|
||||
void torrent::on_lsd_announce_disp(boost::weak_ptr<torrent> p
|
||||
, error_code const& e)
|
||||
void torrent::lsd_announce()
|
||||
{
|
||||
#if defined TORRENT_LOGGING
|
||||
if (e)
|
||||
{
|
||||
boost::shared_ptr<torrent> t = p.lock();
|
||||
if (!t) return;
|
||||
(*t->session().m_logger) << time_now_string() << " on_lsd_announce_disp: " << e.message() << "\n";
|
||||
}
|
||||
#else
|
||||
if (e) return;
|
||||
#endif
|
||||
boost::shared_ptr<torrent> t = p.lock();
|
||||
if (!t) return;
|
||||
t->on_lsd_announce();
|
||||
}
|
||||
|
||||
void torrent::on_lsd_announce()
|
||||
{
|
||||
mutex::scoped_lock l(m_ses.m_mutex);
|
||||
|
||||
if (m_abort) return;
|
||||
|
||||
// if the files haven't been checked yet, we're
|
||||
// not ready for peers
|
||||
if (!m_files_checked) return;
|
||||
|
||||
TORRENT_ASSERT(!m_torrent_file->priv());
|
||||
if (m_torrent_file->is_valid()
|
||||
&& (m_torrent_file->priv()
|
||||
|
@ -1206,36 +1191,39 @@ namespace libtorrent
|
|||
&& !m_settings.allow_i2p_mixed)))
|
||||
return;
|
||||
|
||||
|
||||
if (is_paused()) return;
|
||||
|
||||
boost::weak_ptr<torrent> self(shared_from_this());
|
||||
|
||||
error_code ec;
|
||||
|
||||
// announce on local network every 5 minutes
|
||||
m_lsd_announce_timer.expires_from_now(minutes(5), ec);
|
||||
m_lsd_announce_timer.async_wait(
|
||||
bind(&torrent::on_lsd_announce_disp, self, _1));
|
||||
|
||||
// announce with the local discovery service
|
||||
m_ses.announce_lsd(m_torrent_file->info_hash());
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (!m_ses.m_dht) return;
|
||||
ptime now = time_now();
|
||||
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
||||
|
||||
void torrent::on_dht_announce(error_code const& e)
|
||||
{
|
||||
m_last_dht_announce = now;
|
||||
if (e) return;
|
||||
|
||||
mutex::scoped_lock l(m_ses.m_mutex);
|
||||
if (m_abort) return;
|
||||
|
||||
error_code ec;
|
||||
m_dht_announce_timer.expires_from_now(minutes(15), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
bind(&torrent::on_dht_announce, shared_from_this(), _1));
|
||||
|
||||
if (m_torrent_file->is_valid() && m_torrent_file->priv())
|
||||
return;
|
||||
|
||||
if (is_paused()) return;
|
||||
if (!m_ses.m_dht) return;
|
||||
if (!should_announce_dht()) return;
|
||||
|
||||
m_last_dht_announce = time_now();
|
||||
boost::weak_ptr<torrent> self(shared_from_this());
|
||||
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
||||
, m_ses.listen_port()
|
||||
, bind(&torrent::on_dht_announce_response_disp, self, _1));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
||||
void torrent::on_dht_announce_response_disp(boost::weak_ptr<libtorrent::torrent> t
|
||||
, std::vector<tcp::endpoint> const& peers)
|
||||
{
|
||||
|
@ -1617,7 +1605,7 @@ namespace libtorrent
|
|||
|
||||
#if defined TORRENT_LOGGING
|
||||
if (ec)
|
||||
*m_ses.m_logger << time_now_string() << " on_i2p_resolve: " << e.message() << "\n";
|
||||
*m_ses.m_logger << time_now_string() << " on_i2p_resolve: " << ec.message() << "\n";
|
||||
#endif
|
||||
if (ec || m_ses.is_aborted()) return;
|
||||
|
||||
|
@ -1633,7 +1621,7 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
#if defined TORRENT_LOGGING
|
||||
if (ec)
|
||||
if (e)
|
||||
*m_ses.m_logger << time_now_string() << " on_peer_name_lookup: " << e.message() << "\n";
|
||||
#endif
|
||||
if (e || host == tcp::resolver::iterator() ||
|
||||
|
@ -5270,11 +5258,14 @@ namespace libtorrent
|
|||
&& (!m_torrent_file->is_i2p()
|
||||
|| m_settings.allow_i2p_mixed)))
|
||||
{
|
||||
if (m_ses.m_lsd) lsd_announce();
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
error_code ec;
|
||||
boost::weak_ptr<torrent> self(shared_from_this());
|
||||
m_lsd_announce_timer.expires_from_now(seconds(1), ec);
|
||||
m_lsd_announce_timer.async_wait(
|
||||
bind(&torrent::on_lsd_announce_disp, self, _1));
|
||||
m_dht_announce_timer.expires_from_now(seconds(1), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
bind(&torrent::on_dht_announce, shared_from_this(), _1));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5283,7 +5274,9 @@ namespace libtorrent
|
|||
if (!m_announcing) return;
|
||||
|
||||
error_code ec;
|
||||
m_lsd_announce_timer.cancel(ec);
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
m_dht_announce_timer.cancel(ec);
|
||||
#endif
|
||||
m_tracker_timer.cancel(ec);
|
||||
|
||||
m_announcing = false;
|
||||
|
|
Loading…
Reference in New Issue