fix last_upload, last_download and last_scrape to be reported accurately and saved/restored in resume data

This commit is contained in:
arvidn 2018-04-20 13:03:36 +02:00 committed by Arvid Norberg
parent 44479bcca3
commit 3ede0b9c20
4 changed files with 54 additions and 50 deletions

View File

@ -459,6 +459,15 @@ The file format is a bencoded dictionary containing the following fields:
| | torrent when the resume data was last saved. This is used as |
| | an initial estimate until we acquire up-to-date scrape info. |
+--------------------------+--------------------------------------------------------------+
| ``last_upload`` | integer. The number of seconds since epoch when we last |
| | uploaded payload to a peer on this torrent. |
+--------------------------+--------------------------------------------------------------+
| ``last_download`` | integer. The number of seconds since epoch when we last |
| | downloaded payload from a peer on this torrent. |
+--------------------------+--------------------------------------------------------------+
| ``last_scrape`` | integer. The number of seconds since epoch when we last sent |
| | a scrape request to a tracker on this torrent. |
+--------------------------+--------------------------------------------------------------+
| ``upload_rate_limit`` | integer. In case this torrent has a per-torrent upload rate |
| | limit, this is that limit. In bytes per second. |
+--------------------------+--------------------------------------------------------------+

View File

@ -735,11 +735,7 @@ namespace libtorrent
void scrape_tracker(int idx, bool user_triggered);
void announce_with_tracker(boost::uint8_t e
= tracker_request::none);
int seconds_since_last_scrape() const
{
return m_last_scrape == (std::numeric_limits<boost::int16_t>::min)()
? -1 : int(m_ses.session_time() - m_last_scrape);
}
int seconds_since_last_scrape() const;
#ifndef TORRENT_DISABLE_DHT
void dht_announce();
@ -1089,7 +1085,8 @@ namespace libtorrent
// that are not private
void lsd_announce();
void update_last_upload() { m_last_upload = m_ses.session_time(); }
void update_last_upload()
{ m_last_upload = total_seconds(clock_type::now().time_since_epoch()); }
void set_apply_ip_filter(bool b);
bool apply_ip_filter() const { return m_apply_ip_filter; }
@ -1654,9 +1651,8 @@ namespace libtorrent
// ----
// the timestamp of the last piece passed for this torrent specified in
// session_time. This is signed because it must be able to represent time
// before the session started
boost::int16_t m_last_download;
// seconds since epoch.
boost::uint32_t m_last_download;
// the number of peer connections to seeds. This should be the same as
// counting the peer connections that say true for is_seed()
@ -1667,9 +1663,8 @@ namespace libtorrent
boost::uint16_t m_num_connecting_seeds;
// the timestamp of the last byte uploaded from this torrent specified in
// session_time. This is signed because it must be able to represent time
// before the session started.
boost::int16_t m_last_upload;
// seconds since epoch.
boost::uint32_t m_last_upload;
// this is a second count-down to when we should tick the
// storage for this torrent. Ticking the storage is used
@ -1709,7 +1704,7 @@ namespace libtorrent
// the timestamp of the last scrape request to one of the trackers in
// this torrent specified in session_time. This is signed because it must
// be able to represent time before the session started
boost::int16_t m_last_scrape;
boost::uint32_t m_last_scrape;
// ----

View File

@ -115,6 +115,8 @@ namespace libtorrent
{
namespace {
boost::uint32_t const unset = std::numeric_limits<boost::uint32_t>::max();
bool is_downloading_state(int st)
{
switch (st)
@ -302,17 +304,17 @@ namespace libtorrent
, m_deleted(false)
, m_pinned((p.flags & add_torrent_params::flag_pinned) != 0)
, m_should_be_loaded(true)
, m_last_download((std::numeric_limits<boost::int16_t>::min)())
, m_last_download(unset)
, m_num_seeds(0)
, m_num_connecting_seeds(0)
, m_last_upload((std::numeric_limits<boost::int16_t>::min)())
, m_last_upload(unset)
, m_storage_tick(0)
, m_auto_managed(p.flags & add_torrent_params::flag_auto_managed)
, m_current_gauge_state(no_gauge_state)
, m_moving_storage(false)
, m_inactive(false)
, m_downloaded(0xffffff)
, m_last_scrape((std::numeric_limits<boost::int16_t>::min)())
, m_last_scrape(unset)
, m_progress_ppm(0)
, m_pending_active_change(false)
, m_use_resume_save_path((p.flags & add_torrent_params::flag_use_resume_save_path) != 0)
@ -3393,10 +3395,16 @@ namespace {
update_tracker_timer(now);
}
int torrent::seconds_since_last_scrape() const
{
return m_last_scrape == unset ? -1
: total_seconds(clock_type::now() - time_point(seconds(m_last_scrape)));
}
void torrent::scrape_tracker(int idx, bool user_triggered)
{
TORRENT_ASSERT(is_single_thread());
m_last_scrape = m_ses.session_time();
m_last_scrape = total_seconds(clock_type::now().time_since_epoch());
if (m_trackers.empty()) return;
@ -3555,7 +3563,7 @@ namespace {
update_tracker_timer(now);
if (resp.complete >= 0 && resp.incomplete >= 0)
m_last_scrape = m_ses.session_time();
m_last_scrape = total_seconds(clock_type::now().time_since_epoch());
#ifndef TORRENT_DISABLE_LOGGING
std::string resolved_to;
@ -4403,7 +4411,7 @@ namespace {
// is deallocated by the torrent once it starts seeding
}
m_last_download = m_ses.session_time();
m_last_download = total_seconds(clock_type::now().time_since_epoch());
if (m_share_mode)
recalc_share_mode();
@ -7027,13 +7035,12 @@ namespace {
#endif
}
int now = m_ses.session_time();
int tmp = rd.dict_find_int_value("last_scrape", -1);
m_last_scrape = tmp == -1 ? (std::numeric_limits<boost::int16_t>::min)() : now - tmp;
boost::int64_t tmp = rd.dict_find_int_value("last_scrape", -1);
m_last_scrape = tmp == -1 ? unset : tmp;
tmp = rd.dict_find_int_value("last_download", -1);
m_last_download = tmp == -1 ? (std::numeric_limits<boost::int16_t>::min)() : now - tmp;
m_last_download = tmp == -1 ? unset : tmp;
tmp = rd.dict_find_int_value("last_upload", -1);
m_last_upload = tmp == -1 ? (std::numeric_limits<boost::int16_t>::min)() : now - tmp;
m_last_upload = tmp == -1 ? unset : tmp;
if (m_use_resume_save_path)
{
@ -7275,6 +7282,9 @@ namespace {
ret["num_complete"] = m_complete;
ret["num_incomplete"] = m_incomplete;
ret["num_downloaded"] = m_downloaded;
ret["last_upload"] = m_last_upload == unset ? -1 : boost::int64_t(m_last_upload);
ret["last_download"] = m_last_download == unset ? -1 : boost::int64_t(m_last_download);
ret["last_scrape"] = m_last_scrape == unset ? -1 : boost::int64_t(m_last_scrape);
ret["sequential_download"] = m_sequential_download;
@ -9613,13 +9623,6 @@ namespace {
return a - b;
}
int clamped_subtract_s16(int a, int b)
{
if (a + (std::numeric_limits<boost::int16_t>::min)() < b)
return (std::numeric_limits<boost::int16_t>::min)();
return a - b;
}
} // anonymous namespace
// this is called every time the session timer takes a step back. Since the
@ -9674,10 +9677,6 @@ namespace {
}
m_became_finished = clamped_subtract(m_became_finished, seconds);
m_last_upload = clamped_subtract_s16(m_last_upload, seconds);
m_last_download = clamped_subtract_s16(m_last_download, seconds);
m_last_scrape = clamped_subtract_s16(m_last_scrape, seconds);
m_last_saved_resume = clamped_subtract(m_last_saved_resume, seconds);
m_upload_mode_time = clamped_subtract(m_upload_mode_time, seconds);
}
@ -12145,8 +12144,8 @@ namespace {
st->added_time = m_added_time;
st->completed_time = m_completed_time;
st->last_scrape = m_last_scrape == (std::numeric_limits<boost::int16_t>::min)() ? -1
: clamped_subtract(m_ses.session_time(), m_last_scrape);
st->last_scrape = m_last_scrape == unset ? -1
: total_seconds(clock_type::now() - time_point(seconds(m_last_scrape)));
st->share_mode = m_share_mode;
st->upload_mode = m_upload_mode;
@ -12168,10 +12167,10 @@ namespace {
st->finished_time = finished_time();
st->active_time = active_time();
st->seeding_time = seeding_time();
st->time_since_upload = m_last_upload == (std::numeric_limits<boost::int16_t>::min)() ? -1
: clamped_subtract(m_ses.session_time(), m_last_upload);
st->time_since_download = m_last_download == (std::numeric_limits<boost::int16_t>::min)() ? -1
: clamped_subtract(m_ses.session_time(), m_last_download);
st->time_since_upload = m_last_upload == unset ? -1
: total_seconds(clock_type::now() - time_point(seconds(m_last_upload)));
st->time_since_download = m_last_download == unset ? -1
: total_seconds(clock_type::now() - time_point(seconds(m_last_download)));
st->storage_mode = static_cast<storage_mode_t>(m_storage_mode);

View File

@ -99,9 +99,9 @@ std::vector<char> generate_resume_data(torrent_info* ti
rd["super_seeding"] = 0;
rd["added_time"] = 1347;
rd["completed_time"] = 1348;
rd["last_scrape"] = 1349;
rd["last_download"] = 1350;
rd["last_upload"] = 1351;
rd["last_scrape"] = 1;
rd["last_download"] = 2;
rd["last_upload"] = 3;
rd["finished_time"] = 1352;
if (file_priorities && file_priorities[0])
{
@ -177,14 +177,15 @@ void default_tests(torrent_status const& s)
// allow some slack in the time stamps since they are reported as
// relative times. If the computer is busy while running the unit test
// or running under valgrind it may take several seconds
TEST_CHECK(s.last_scrape >= 1349);
TEST_CHECK(s.time_since_download >= 1350);
TEST_CHECK(s.time_since_upload >= 1351);
int const now = duration_cast<seconds>(clock_type::now().time_since_epoch()).count();
TEST_CHECK(s.last_scrape >= now - 1);
TEST_CHECK(s.time_since_download >= now - 2);
TEST_CHECK(s.time_since_upload >= now - 3);
TEST_CHECK(s.active_time >= 1339);
TEST_CHECK(s.last_scrape < 1349 + 10);
TEST_CHECK(s.time_since_download < 1350 + 10);
TEST_CHECK(s.time_since_upload < 1351 + 10);
TEST_CHECK(s.last_scrape < now - 1 + 10);
TEST_CHECK(s.time_since_download < now - 2 + 10);
TEST_CHECK(s.time_since_upload < now - 3 + 10);
TEST_CHECK(s.active_time < 1339 + 10);
TEST_CHECK(s.finished_time >= 1352);