add per-tracker scrape information to announce_entry

This commit is contained in:
Arvid Norberg 2013-02-04 07:17:31 +00:00
parent 8a55d7e32b
commit 7607f20e2a
9 changed files with 84 additions and 24 deletions

View File

@ -1,3 +1,4 @@
* add per-tracker scrape information to announce_entry
* report errors in read_piece_alert * report errors in read_piece_alert
* DHT memory optimization * DHT memory optimization
* improve DHT lookup speed * improve DHT lookup speed

View File

@ -2126,6 +2126,10 @@ ones with lower tier will always be tried before the one with higher tier number
int next_announce_in() const; int next_announce_in() const;
int min_announce_in() const; int min_announce_in() const;
int scrape_incomplete;
int scrape_complete;
int scrape_downloaded;
error_code last_error; error_code last_error;
std::string message; std::string message;
@ -2156,6 +2160,13 @@ allowed to force another tracker update with this tracker.
If the last time this tracker was contacted failed, ``last_error`` is the error If the last time this tracker was contacted failed, ``last_error`` is the error
code describing what error occurred. code describing what error occurred.
``scrape_incomplete``, ``scrape_complete`` and ``scrape_downloaded`` are either
-1 or the scrape information this tracker last responded with. *incomplete* is
the current number of downloaders in the swarm, *complete* is the current number
of seeds in the swarm and *downloaded* is the cumulative number of completed
downloads of this torrent, since the beginning of time (from this tracker's point
of view).
If the last time this tracker was contacted, the tracker returned a warning If the last time this tracker was contacted, the tracker returned a warning
or error message, ``message`` contains that message. or error message, ``message`` contains that message.
@ -6703,8 +6714,9 @@ the DHT.
int num_peers; int num_peers;
}; };
The ``num_peers`` tells how many peers were returned from the tracker. This is The ``num_peers`` tells how many peers the tracker returned in this response. This is
not necessarily all new peers, some of them may already be connected. not expected to be more thant the ``num_want`` settings. These are not necessarily
all new peers, some of them may already be connected.
tracker_warning_alert tracker_warning_alert
--------------------- ---------------------

View File

@ -448,8 +448,8 @@ namespace libtorrent
, address const& tracker_ip , address const& tracker_ip
, std::list<address> const& ip_list , std::list<address> const& ip_list
, std::vector<peer_entry>& e, int interval, int min_interval , std::vector<peer_entry>& e, int interval, int min_interval
, int complete, int incomplete, address const& external_ip , int complete, int incomplete, int downloaded
, std::string const& trackerid); , address const& external_ip, std::string const& trackerid);
virtual void tracker_request_error(tracker_request const& r virtual void tracker_request_error(tracker_request const& r
, int response_code, error_code const& ec, const std::string& msg , int response_code, error_code const& ec, const std::string& msg
, int retry_interval); , int retry_interval);
@ -458,6 +458,8 @@ namespace libtorrent
virtual void tracker_scrape_response(tracker_request const& req virtual void tracker_scrape_response(tracker_request const& req
, int complete, int incomplete, int downloaded, int downloaders); , int complete, int incomplete, int downloaded, int downloaders);
void update_scrape_state();
// if no password and username is set // if no password and username is set
// this will return an empty string, otherwise // this will return an empty string, otherwise
// it will concatenate the login and password // it will concatenate the login and password
@ -1338,7 +1340,7 @@ namespace libtorrent
// the scrape data from the tracker response, this // the scrape data from the tracker response, this
// is optional and may be 0xffffff // is optional and may be 0xffffff
unsigned int m_downloaders:24; unsigned int m_downloaded:24;
// round-robin index into m_interfaces // round-robin index into m_interfaces
mutable boost::uint8_t m_interface_index; mutable boost::uint8_t m_interface_index;

View File

@ -105,6 +105,17 @@ namespace libtorrent
// no announces before this time // no announces before this time
ptime min_announce; ptime min_announce;
// TODO: include the number of peers received from this tracker, at last announce
// if this tracker has returned scrape data, these fields are filled
// in with valid numbers. Otherwise they are set to -1.
// the number of current downloaders
int scrape_incomplete;
// the number of current seeds
int scrape_complete;
// the cumulative number of completed downloads, ever
int scrape_downloaded;
// the tier this tracker belongs to // the tier this tracker belongs to
boost::uint8_t tier; boost::uint8_t tier;

View File

@ -156,6 +156,7 @@ namespace libtorrent
, int min_interval , int min_interval
, int complete , int complete
, int incomplete , int incomplete
, int downloaded
, address const& external_ip , address const& external_ip
, std::string const& trackerid) = 0; , std::string const& trackerid) = 0;
virtual void tracker_request_error( virtual void tracker_request_error(

View File

@ -527,6 +527,7 @@ namespace libtorrent
int complete = int(e.dict_find_int_value("complete", -1)); int complete = int(e.dict_find_int_value("complete", -1));
int incomplete = int(e.dict_find_int_value("incomplete", -1)); int incomplete = int(e.dict_find_int_value("incomplete", -1));
int downloaded = int(e.dict_find_int_value("downloaded", -1));
std::list<address> ip_list; std::list<address> ip_list;
if (m_tracker_connection) if (m_tracker_connection)
@ -542,7 +543,7 @@ namespace libtorrent
} }
cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, peer_list cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, peer_list
, interval, min_interval, complete, incomplete, external_ip, trackerid); , interval, min_interval, complete, incomplete, downloaded, external_ip, trackerid);
} }
} }

View File

@ -415,7 +415,7 @@ namespace libtorrent
, m_last_download(0) , m_last_download(0)
, m_last_upload(0) , m_last_upload(0)
, m_last_scrape(0) , m_last_scrape(0)
, m_downloaders(0xffffff) , m_downloaded(0xffffff)
, m_interface_index(0) , m_interface_index(0)
, m_graceful_pause_mode(false) , m_graceful_pause_mode(false)
, m_need_connect_boost(true) , m_need_connect_boost(true)
@ -2470,21 +2470,47 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(req.kind == tracker_request::scrape_request); TORRENT_ASSERT(req.kind == tracker_request::scrape_request);
if ((complete >= 0 && m_complete != complete) announce_entry* ae = find_tracker(req);
|| (incomplete >= 0 && m_incomplete != incomplete) if (ae)
|| (downloaders >= 0 && m_downloaders != downloaders)) {
state_updated(); if (incomplete >= 0) ae->scrape_incomplete = incomplete;
if (complete >= 0) ae->scrape_complete = complete;
if (downloaded >= 0) ae->scrape_downloaded = downloaded;
if (complete >= 0) m_complete = complete; update_scrape_state();
if (incomplete >= 0) m_incomplete = incomplete; }
if (downloaders >= 0) m_downloaders = downloaders;
if (m_ses.m_alerts.should_post<scrape_reply_alert>()) if (m_ses.m_alerts.should_post<scrape_reply_alert>())
{ {
m_ses.m_alerts.post_alert(scrape_reply_alert( m_ses.m_alerts.post_alert(scrape_reply_alert(
get_handle(), m_incomplete, m_complete, req.url)); get_handle(), incomplete, complete, req.url));
} }
} }
void torrent::update_scrape_state()
{
// loop over all trackers and find the largest numbers for each scrape field
// then update the torrent-wide understanding of number of downloaders and seeds
int complete = -1;
int incomplete = -1;
int downloaded = -1;
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
, end(m_trackers.end()); i != end; ++i)
{
complete = (std::max)(i->scrape_complete, complete);
incomplete = (std::max)(i->scrape_incomplete, incomplete);
downloaded = (std::max)(i->scrape_downloaded, downloaded);
}
if ((complete >= 0 && m_complete != complete)
|| (incomplete >= 0 && m_incomplete != incomplete)
|| (downloaded >= 0 && m_downloaded != downloaded))
state_updated();
m_complete = complete;
m_incomplete = incomplete;
m_downloaded = downloaded;
}
void torrent::tracker_response( void torrent::tracker_response(
tracker_request const& r tracker_request const& r
@ -2495,6 +2521,7 @@ namespace libtorrent
, int min_interval , int min_interval
, int complete , int complete
, int incomplete , int incomplete
, int downloaded
, address const& external_ip , address const& external_ip
, const std::string& trackerid) , const std::string& trackerid)
{ {
@ -2516,6 +2543,9 @@ namespace libtorrent
announce_entry* ae = find_tracker(r); announce_entry* ae = find_tracker(r);
if (ae) if (ae)
{ {
if (incomplete >= 0) ae->scrape_incomplete = incomplete;
if (complete >= 0) ae->scrape_complete = complete;
if (downloaded >= 0) ae->scrape_downloaded = downloaded;
if (!ae->start_sent && r.event == tracker_request::started) if (!ae->start_sent && r.event == tracker_request::started)
ae->start_sent = true; ae->start_sent = true;
if (!ae->complete_sent && r.event == tracker_request::completed) if (!ae->complete_sent && r.event == tracker_request::completed)
@ -2534,11 +2564,11 @@ namespace libtorrent
if (m_ses.m_alerts.should_post<trackerid_alert>()) if (m_ses.m_alerts.should_post<trackerid_alert>())
m_ses.m_alerts.post_alert(trackerid_alert(get_handle(), r.url, trackerid)); m_ses.m_alerts.post_alert(trackerid_alert(get_handle(), r.url, trackerid));
} }
update_scrape_state();
} }
update_tracker_timer(now); update_tracker_timer(now);
if (complete >= 0) m_complete = complete;
if (incomplete >= 0) m_incomplete = incomplete;
if (complete >= 0 && incomplete >= 0) if (complete >= 0 && incomplete >= 0)
m_last_scrape = 0; m_last_scrape = 0;
@ -5033,9 +5063,9 @@ namespace libtorrent
m_finished_time = rd.dict_find_int_value("finished_time"); m_finished_time = rd.dict_find_int_value("finished_time");
m_seeding_time = rd.dict_find_int_value("seeding_time"); m_seeding_time = rd.dict_find_int_value("seeding_time");
m_last_seen_complete = rd.dict_find_int_value("last_seen_complete"); m_last_seen_complete = rd.dict_find_int_value("last_seen_complete");
m_complete = rd.dict_find_int_value("num_seeds", 0xffffff); m_complete = rd.dict_find_int_value("num_complete", 0xffffff);
m_incomplete = rd.dict_find_int_value("num_incomplete", 0xffffff); m_incomplete = rd.dict_find_int_value("num_incomplete", 0xffffff);
m_downloaders = rd.dict_find_int_value("num_downloaders", 0xffffff); m_downloaded = rd.dict_find_int_value("num_downloaded", 0xffffff);
set_upload_limit(rd.dict_find_int_value("upload_rate_limit", -1)); set_upload_limit(rd.dict_find_int_value("upload_rate_limit", -1));
set_download_limit(rd.dict_find_int_value("download_rate_limit", -1)); set_download_limit(rd.dict_find_int_value("download_rate_limit", -1));
set_max_connections(rd.dict_find_int_value("max_connections", -1)); set_max_connections(rd.dict_find_int_value("max_connections", -1));
@ -5231,9 +5261,9 @@ namespace libtorrent
ret["seeding_time"] = m_seeding_time; ret["seeding_time"] = m_seeding_time;
ret["last_seen_complete"] = m_last_seen_complete; ret["last_seen_complete"] = m_last_seen_complete;
ret["num_seeds"] = m_complete; ret["num_complete"] = m_complete;
ret["num_incomplete"] = m_incomplete; ret["num_incomplete"] = m_incomplete;
ret["num_downloaders"] = m_downloaders; ret["num_downloaded"] = m_downloaded;
ret["sequential_download"] = m_sequential_download; ret["sequential_download"] = m_sequential_download;
@ -7063,8 +7093,7 @@ namespace libtorrent
if (m_complete != 0xffffff) seeds = m_complete; if (m_complete != 0xffffff) seeds = m_complete;
else seeds = m_policy.num_seeds(); else seeds = m_policy.num_seeds();
if (m_downloaders != 0xffffff) downloaders = m_downloaders; if (m_incomplete != 0xffffff) downloaders = m_incomplete;
else if (m_incomplete != 0xffffff) downloaders = m_incomplete;
else downloaders = m_policy.num_peers() - m_policy.num_seeds(); else downloaders = m_policy.num_peers() - m_policy.num_seeds();
if (seeds == 0) if (seeds == 0)

View File

@ -454,6 +454,9 @@ namespace libtorrent
: url(u) : url(u)
, next_announce(min_time()) , next_announce(min_time())
, min_announce(min_time()) , min_announce(min_time())
, scrape_incomplete(-1)
, scrape_complete(-1)
, scrape_downloaded(-1)
, tier(0) , tier(0)
, fail_limit(0) , fail_limit(0)
, fails(0) , fails(0)

View File

@ -569,7 +569,7 @@ namespace libtorrent
} }
cb->tracker_response(tracker_req(), m_target.address(), ip_list cb->tracker_response(tracker_req(), m_target.address(), ip_list
, peer_list, interval, min_interval, complete, incomplete, address(), "" /*trackerid*/); , peer_list, interval, min_interval, complete, incomplete, 0, address(), "" /*trackerid*/);
close(); close();
return true; return true;