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
* DHT memory optimization
* 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 min_announce_in() const;
int scrape_incomplete;
int scrape_complete;
int scrape_downloaded;
error_code last_error;
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
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
or error message, ``message`` contains that message.
@ -6703,8 +6714,9 @@ the DHT.
int num_peers;
};
The ``num_peers`` tells how many peers were returned from the tracker. This is
not necessarily all new peers, some of them may already be connected.
The ``num_peers`` tells how many peers the tracker returned in this response. This is
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
---------------------

View File

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

View File

@ -105,6 +105,17 @@ namespace libtorrent
// no announces before this time
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
boost::uint8_t tier;

View File

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

View File

@ -527,6 +527,7 @@ namespace libtorrent
int complete = int(e.dict_find_int_value("complete", -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;
if (m_tracker_connection)
@ -542,7 +543,7 @@ namespace libtorrent
}
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_upload(0)
, m_last_scrape(0)
, m_downloaders(0xffffff)
, m_downloaded(0xffffff)
, m_interface_index(0)
, m_graceful_pause_mode(false)
, m_need_connect_boost(true)
@ -2470,21 +2470,47 @@ namespace libtorrent
INVARIANT_CHECK;
TORRENT_ASSERT(req.kind == tracker_request::scrape_request);
if ((complete >= 0 && m_complete != complete)
|| (incomplete >= 0 && m_incomplete != incomplete)
|| (downloaders >= 0 && m_downloaders != downloaders))
state_updated();
announce_entry* ae = find_tracker(req);
if (ae)
{
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;
if (incomplete >= 0) m_incomplete = incomplete;
if (downloaders >= 0) m_downloaders = downloaders;
update_scrape_state();
}
if (m_ses.m_alerts.should_post<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(
tracker_request const& r
@ -2495,6 +2521,7 @@ namespace libtorrent
, int min_interval
, int complete
, int incomplete
, int downloaded
, address const& external_ip
, const std::string& trackerid)
{
@ -2516,6 +2543,9 @@ namespace libtorrent
announce_entry* ae = find_tracker(r);
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)
ae->start_sent = true;
if (!ae->complete_sent && r.event == tracker_request::completed)
@ -2534,11 +2564,11 @@ namespace libtorrent
if (m_ses.m_alerts.should_post<trackerid_alert>())
m_ses.m_alerts.post_alert(trackerid_alert(get_handle(), r.url, trackerid));
}
update_scrape_state();
}
update_tracker_timer(now);
if (complete >= 0) m_complete = complete;
if (incomplete >= 0) m_incomplete = incomplete;
if (complete >= 0 && incomplete >= 0)
m_last_scrape = 0;
@ -5033,9 +5063,9 @@ namespace libtorrent
m_finished_time = rd.dict_find_int_value("finished_time");
m_seeding_time = rd.dict_find_int_value("seeding_time");
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_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_download_limit(rd.dict_find_int_value("download_rate_limit", -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["last_seen_complete"] = m_last_seen_complete;
ret["num_seeds"] = m_complete;
ret["num_complete"] = m_complete;
ret["num_incomplete"] = m_incomplete;
ret["num_downloaders"] = m_downloaders;
ret["num_downloaded"] = m_downloaded;
ret["sequential_download"] = m_sequential_download;
@ -7063,8 +7093,7 @@ namespace libtorrent
if (m_complete != 0xffffff) seeds = m_complete;
else seeds = m_policy.num_seeds();
if (m_downloaders != 0xffffff) downloaders = m_downloaders;
else if (m_incomplete != 0xffffff) downloaders = m_incomplete;
if (m_incomplete != 0xffffff) downloaders = m_incomplete;
else downloaders = m_policy.num_peers() - m_policy.num_seeds();
if (seeds == 0)

View File

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

View File

@ -569,7 +569,7 @@ namespace libtorrent
}
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();
return true;