fix last_upload, last_download and last_scrape to be reported accurately and saved/restored in resume data
This commit is contained in:
parent
44479bcca3
commit
3ede0b9c20
|
@ -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 |
|
| | torrent when the resume data was last saved. This is used as |
|
||||||
| | an initial estimate until we acquire up-to-date scrape info. |
|
| | 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 |
|
| ``upload_rate_limit`` | integer. In case this torrent has a per-torrent upload rate |
|
||||||
| | limit, this is that limit. In bytes per second. |
|
| | limit, this is that limit. In bytes per second. |
|
||||||
+--------------------------+--------------------------------------------------------------+
|
+--------------------------+--------------------------------------------------------------+
|
||||||
|
|
|
@ -735,11 +735,7 @@ namespace libtorrent
|
||||||
void scrape_tracker(int idx, bool user_triggered);
|
void scrape_tracker(int idx, bool user_triggered);
|
||||||
void announce_with_tracker(boost::uint8_t e
|
void announce_with_tracker(boost::uint8_t e
|
||||||
= tracker_request::none);
|
= tracker_request::none);
|
||||||
int seconds_since_last_scrape() const
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
void dht_announce();
|
void dht_announce();
|
||||||
|
@ -1089,7 +1085,8 @@ namespace libtorrent
|
||||||
// that are not private
|
// that are not private
|
||||||
void lsd_announce();
|
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);
|
void set_apply_ip_filter(bool b);
|
||||||
bool apply_ip_filter() const { return m_apply_ip_filter; }
|
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
|
// 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
|
// seconds since epoch.
|
||||||
// before the session started
|
boost::uint32_t m_last_download;
|
||||||
boost::int16_t m_last_download;
|
|
||||||
|
|
||||||
// the number of peer connections to seeds. This should be the same as
|
// the number of peer connections to seeds. This should be the same as
|
||||||
// counting the peer connections that say true for is_seed()
|
// counting the peer connections that say true for is_seed()
|
||||||
|
@ -1667,9 +1663,8 @@ namespace libtorrent
|
||||||
boost::uint16_t m_num_connecting_seeds;
|
boost::uint16_t m_num_connecting_seeds;
|
||||||
|
|
||||||
// the timestamp of the last byte uploaded from this torrent specified in
|
// 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
|
// seconds since epoch.
|
||||||
// before the session started.
|
boost::uint32_t m_last_upload;
|
||||||
boost::int16_t m_last_upload;
|
|
||||||
|
|
||||||
// this is a second count-down to when we should tick the
|
// this is a second count-down to when we should tick the
|
||||||
// storage for this torrent. Ticking the storage is used
|
// 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
|
// 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
|
// this torrent specified in session_time. This is signed because it must
|
||||||
// be able to represent time before the session started
|
// be able to represent time before the session started
|
||||||
boost::int16_t m_last_scrape;
|
boost::uint32_t m_last_scrape;
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
boost::uint32_t const unset = std::numeric_limits<boost::uint32_t>::max();
|
||||||
|
|
||||||
bool is_downloading_state(int st)
|
bool is_downloading_state(int st)
|
||||||
{
|
{
|
||||||
switch (st)
|
switch (st)
|
||||||
|
@ -302,17 +304,17 @@ namespace libtorrent
|
||||||
, m_deleted(false)
|
, m_deleted(false)
|
||||||
, m_pinned((p.flags & add_torrent_params::flag_pinned) != 0)
|
, m_pinned((p.flags & add_torrent_params::flag_pinned) != 0)
|
||||||
, m_should_be_loaded(true)
|
, 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_seeds(0)
|
||||||
, m_num_connecting_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_storage_tick(0)
|
||||||
, m_auto_managed(p.flags & add_torrent_params::flag_auto_managed)
|
, m_auto_managed(p.flags & add_torrent_params::flag_auto_managed)
|
||||||
, m_current_gauge_state(no_gauge_state)
|
, m_current_gauge_state(no_gauge_state)
|
||||||
, m_moving_storage(false)
|
, m_moving_storage(false)
|
||||||
, m_inactive(false)
|
, m_inactive(false)
|
||||||
, m_downloaded(0xffffff)
|
, m_downloaded(0xffffff)
|
||||||
, m_last_scrape((std::numeric_limits<boost::int16_t>::min)())
|
, m_last_scrape(unset)
|
||||||
, m_progress_ppm(0)
|
, m_progress_ppm(0)
|
||||||
, m_pending_active_change(false)
|
, m_pending_active_change(false)
|
||||||
, m_use_resume_save_path((p.flags & add_torrent_params::flag_use_resume_save_path) != 0)
|
, 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);
|
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)
|
void torrent::scrape_tracker(int idx, bool user_triggered)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_single_thread());
|
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;
|
if (m_trackers.empty()) return;
|
||||||
|
|
||||||
|
@ -3555,7 +3563,7 @@ namespace {
|
||||||
update_tracker_timer(now);
|
update_tracker_timer(now);
|
||||||
|
|
||||||
if (resp.complete >= 0 && resp.incomplete >= 0)
|
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
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
std::string resolved_to;
|
std::string resolved_to;
|
||||||
|
@ -4403,7 +4411,7 @@ namespace {
|
||||||
// is deallocated by the torrent once it starts seeding
|
// 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)
|
if (m_share_mode)
|
||||||
recalc_share_mode();
|
recalc_share_mode();
|
||||||
|
@ -7027,13 +7035,12 @@ namespace {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int now = m_ses.session_time();
|
boost::int64_t tmp = rd.dict_find_int_value("last_scrape", -1);
|
||||||
int tmp = rd.dict_find_int_value("last_scrape", -1);
|
m_last_scrape = tmp == -1 ? unset : tmp;
|
||||||
m_last_scrape = tmp == -1 ? (std::numeric_limits<boost::int16_t>::min)() : now - tmp;
|
|
||||||
tmp = rd.dict_find_int_value("last_download", -1);
|
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);
|
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)
|
if (m_use_resume_save_path)
|
||||||
{
|
{
|
||||||
|
@ -7275,6 +7282,9 @@ namespace {
|
||||||
ret["num_complete"] = m_complete;
|
ret["num_complete"] = m_complete;
|
||||||
ret["num_incomplete"] = m_incomplete;
|
ret["num_incomplete"] = m_incomplete;
|
||||||
ret["num_downloaded"] = m_downloaded;
|
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;
|
ret["sequential_download"] = m_sequential_download;
|
||||||
|
|
||||||
|
@ -9613,13 +9623,6 @@ namespace {
|
||||||
return a - b;
|
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
|
} // anonymous namespace
|
||||||
|
|
||||||
// this is called every time the session timer takes a step back. Since the
|
// 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_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_last_saved_resume = clamped_subtract(m_last_saved_resume, seconds);
|
||||||
m_upload_mode_time = clamped_subtract(m_upload_mode_time, seconds);
|
m_upload_mode_time = clamped_subtract(m_upload_mode_time, seconds);
|
||||||
}
|
}
|
||||||
|
@ -12145,8 +12144,8 @@ namespace {
|
||||||
st->added_time = m_added_time;
|
st->added_time = m_added_time;
|
||||||
st->completed_time = m_completed_time;
|
st->completed_time = m_completed_time;
|
||||||
|
|
||||||
st->last_scrape = m_last_scrape == (std::numeric_limits<boost::int16_t>::min)() ? -1
|
st->last_scrape = m_last_scrape == unset ? -1
|
||||||
: clamped_subtract(m_ses.session_time(), m_last_scrape);
|
: total_seconds(clock_type::now() - time_point(seconds(m_last_scrape)));
|
||||||
|
|
||||||
st->share_mode = m_share_mode;
|
st->share_mode = m_share_mode;
|
||||||
st->upload_mode = m_upload_mode;
|
st->upload_mode = m_upload_mode;
|
||||||
|
@ -12168,10 +12167,10 @@ namespace {
|
||||||
st->finished_time = finished_time();
|
st->finished_time = finished_time();
|
||||||
st->active_time = active_time();
|
st->active_time = active_time();
|
||||||
st->seeding_time = seeding_time();
|
st->seeding_time = seeding_time();
|
||||||
st->time_since_upload = m_last_upload == (std::numeric_limits<boost::int16_t>::min)() ? -1
|
st->time_since_upload = m_last_upload == unset ? -1
|
||||||
: clamped_subtract(m_ses.session_time(), m_last_upload);
|
: total_seconds(clock_type::now() - time_point(seconds(m_last_upload)));
|
||||||
st->time_since_download = m_last_download == (std::numeric_limits<boost::int16_t>::min)() ? -1
|
st->time_since_download = m_last_download == unset ? -1
|
||||||
: clamped_subtract(m_ses.session_time(), m_last_download);
|
: total_seconds(clock_type::now() - time_point(seconds(m_last_download)));
|
||||||
|
|
||||||
st->storage_mode = static_cast<storage_mode_t>(m_storage_mode);
|
st->storage_mode = static_cast<storage_mode_t>(m_storage_mode);
|
||||||
|
|
||||||
|
|
|
@ -99,9 +99,9 @@ std::vector<char> generate_resume_data(torrent_info* ti
|
||||||
rd["super_seeding"] = 0;
|
rd["super_seeding"] = 0;
|
||||||
rd["added_time"] = 1347;
|
rd["added_time"] = 1347;
|
||||||
rd["completed_time"] = 1348;
|
rd["completed_time"] = 1348;
|
||||||
rd["last_scrape"] = 1349;
|
rd["last_scrape"] = 1;
|
||||||
rd["last_download"] = 1350;
|
rd["last_download"] = 2;
|
||||||
rd["last_upload"] = 1351;
|
rd["last_upload"] = 3;
|
||||||
rd["finished_time"] = 1352;
|
rd["finished_time"] = 1352;
|
||||||
if (file_priorities && file_priorities[0])
|
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
|
// allow some slack in the time stamps since they are reported as
|
||||||
// relative times. If the computer is busy while running the unit test
|
// relative times. If the computer is busy while running the unit test
|
||||||
// or running under valgrind it may take several seconds
|
// or running under valgrind it may take several seconds
|
||||||
TEST_CHECK(s.last_scrape >= 1349);
|
int const now = duration_cast<seconds>(clock_type::now().time_since_epoch()).count();
|
||||||
TEST_CHECK(s.time_since_download >= 1350);
|
TEST_CHECK(s.last_scrape >= now - 1);
|
||||||
TEST_CHECK(s.time_since_upload >= 1351);
|
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.active_time >= 1339);
|
||||||
|
|
||||||
TEST_CHECK(s.last_scrape < 1349 + 10);
|
TEST_CHECK(s.last_scrape < now - 1 + 10);
|
||||||
TEST_CHECK(s.time_since_download < 1350 + 10);
|
TEST_CHECK(s.time_since_download < now - 2 + 10);
|
||||||
TEST_CHECK(s.time_since_upload < 1351 + 10);
|
TEST_CHECK(s.time_since_upload < now - 3 + 10);
|
||||||
TEST_CHECK(s.active_time < 1339 + 10);
|
TEST_CHECK(s.active_time < 1339 + 10);
|
||||||
|
|
||||||
TEST_CHECK(s.finished_time >= 1352);
|
TEST_CHECK(s.finished_time >= 1352);
|
||||||
|
|
Loading…
Reference in New Issue