mirror of
https://github.com/transmission/transmission
synced 2024-07-08 19:55:54 +00:00
feat: added sleep-per-seconds-during-verify
to settings.json (#6572)
* feat: added `sleep-per-seconds-during-verify` to settings.json * Ensuring `sleep_per_seconds_during_verify > 0` in `verify_torrent` for better performance * `#include` list reordered alphabetically * fix: `[readability-inconsistent-declaration-parameter-name]` warning
This commit is contained in:
parent
cf84afda8c
commit
f06cb37c06
|
@ -91,6 +91,7 @@ Here is a sample of the three basic types: respectively Boolean, Number and Stri
|
|||
* **torrent-added-verify-mode:** String ("fast", "full", default: "fast") Whether newly-added torrents' local data should be fully verified when added, or wait and verify them on-demand later. See [#2626](https://github.com/transmission/transmission/pull/2626) for more discussion.
|
||||
* **utp-enabled:** Boolean (default = true) Enable [Micro Transport Protocol (µTP)](https://en.wikipedia.org/wiki/Micro_Transport_Protocol)
|
||||
* **preferred-transport:** String ("utp" = Prefer µTP, "tcp" = Prefer TCP; default = "utp") Choose your preferred transport protocol (has no effect if one of them is disabled).
|
||||
* **sleep-per-seconds-during-verify:** Number (default = 100) Controls the duration in milliseconds for which the verification process will pause to reduce disk I/O pressure.
|
||||
|
||||
#### Peers
|
||||
* **bind-address-ipv4:** String (default = "") Where to listen for peer connections. When no valid IPv4 address is provided, Transmission will bind to "0.0.0.0".
|
||||
|
|
|
@ -351,6 +351,7 @@ auto constexpr MyStatic = std::array<std::string_view, TR_N_KEYS>{
|
|||
"size-bytes"sv,
|
||||
"size-units"sv,
|
||||
"sizeWhenDone"sv,
|
||||
"sleep-per-seconds-during-verify"sv,
|
||||
"sort-mode"sv,
|
||||
"sort-reversed"sv,
|
||||
"source"sv,
|
||||
|
|
|
@ -352,6 +352,7 @@ enum
|
|||
TR_KEY_size_bytes,
|
||||
TR_KEY_size_units,
|
||||
TR_KEY_sizeWhenDone,
|
||||
TR_KEY_sleep_per_seconds_during_verify,
|
||||
TR_KEY_sort_mode,
|
||||
TR_KEY_sort_reversed,
|
||||
TR_KEY_source,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <chrono> // for tr_sleep_per_seconds_during_verify
|
||||
#include <cstddef> // for size_t
|
||||
#include <string>
|
||||
|
||||
|
@ -67,6 +68,7 @@ struct tr_variant;
|
|||
V(TR_KEY_script_torrent_done_seeding_filename, script_torrent_done_seeding_filename, std::string, "", "") \
|
||||
V(TR_KEY_seed_queue_enabled, seed_queue_enabled, bool, false, "") \
|
||||
V(TR_KEY_seed_queue_size, seed_queue_size, size_t, 10U, "") \
|
||||
V(TR_KEY_sleep_per_seconds_during_verify, sleep_per_seconds_during_verify, std::chrono::milliseconds, 100, "") \
|
||||
V(TR_KEY_speed_limit_down, speed_limit_down, size_t, 100U, "") \
|
||||
V(TR_KEY_speed_limit_down_enabled, speed_limit_down_enabled, bool, false, "") \
|
||||
V(TR_KEY_speed_limit_up, speed_limit_up, size_t, 100U, "") \
|
||||
|
|
|
@ -871,6 +871,12 @@ void tr_session::setSettings(tr_session_settings&& settings_in, bool force)
|
|||
dht_ = tr_dht::create(dht_mediator_, localPeerPort(), udp_core_->socket4(), udp_core_->socket6());
|
||||
}
|
||||
|
||||
if (auto const& val = new_settings.sleep_per_seconds_during_verify;
|
||||
force || val != old_settings.sleep_per_seconds_during_verify)
|
||||
{
|
||||
verifier_->set_sleep_per_seconds_during_verify(val);
|
||||
}
|
||||
|
||||
// We need to update bandwidth if speed settings changed.
|
||||
// It's a harmless call, so just call it instead of checking for settings changes
|
||||
update_bandwidth(TR_UP);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <chrono> //std::chrono::milliseconds
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
|
@ -424,4 +425,21 @@ tr_variant VariantConverter::save<tr_verify_added_mode>(tr_verify_added_mode con
|
|||
return static_cast<int64_t>(val);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::optional<std::chrono::milliseconds> VariantConverter::load<std::chrono::milliseconds>(tr_variant const& src)
|
||||
{
|
||||
if (auto val = src.get_if<int64_t>(); val != nullptr)
|
||||
{
|
||||
return std::chrono::milliseconds(*val);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template<>
|
||||
tr_variant VariantConverter::save<std::chrono::milliseconds>(std::chrono::milliseconds const& val)
|
||||
{
|
||||
return val.count();
|
||||
}
|
||||
|
||||
} // namespace libtransmission
|
||||
|
|
|
@ -25,15 +25,16 @@ using namespace std::chrono_literals;
|
|||
|
||||
namespace
|
||||
{
|
||||
auto constexpr SleepPerSecondDuringVerify = 100ms;
|
||||
|
||||
[[nodiscard]] auto current_time_secs()
|
||||
{
|
||||
return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::steady_clock::now());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void tr_verify_worker::verify_torrent(Mediator& verify_mediator, std::atomic<bool> const& abort_flag)
|
||||
void tr_verify_worker::verify_torrent(
|
||||
Mediator& verify_mediator,
|
||||
std::atomic<bool> const& abort_flag,
|
||||
std::chrono::milliseconds const sleep_per_seconds_during_verify)
|
||||
{
|
||||
verify_mediator.on_verify_started();
|
||||
|
||||
|
@ -89,12 +90,15 @@ void tr_verify_worker::verify_torrent(Mediator& verify_mediator, std::atomic<boo
|
|||
auto const has_piece = sha->finish() == metainfo.piece_hash(piece);
|
||||
verify_mediator.on_piece_checked(piece, has_piece);
|
||||
|
||||
/* sleeping even just a few msec per second goes a long
|
||||
* way towards reducing IO load... */
|
||||
if (auto const now = current_time_secs(); last_slept_at != now)
|
||||
if (sleep_per_seconds_during_verify > std::chrono::milliseconds::zero())
|
||||
{
|
||||
last_slept_at = now;
|
||||
std::this_thread::sleep_for(SleepPerSecondDuringVerify);
|
||||
/* sleeping even just a few msec per second goes a long
|
||||
* way towards reducing IO load... */
|
||||
if (auto const now = current_time_secs(); last_slept_at != now)
|
||||
{
|
||||
last_slept_at = now;
|
||||
std::this_thread::sleep_for(sleep_per_seconds_during_verify);
|
||||
}
|
||||
}
|
||||
|
||||
sha->clear();
|
||||
|
@ -148,7 +152,7 @@ void tr_verify_worker::verify_thread_func()
|
|||
current_node_ = std::move(todo_.extract(std::begin(todo_)).value());
|
||||
}
|
||||
|
||||
verify_torrent(*current_node_->mediator_, stop_current_);
|
||||
verify_torrent(*current_node_->mediator_, stop_current_, sleep_per_seconds_during_verify_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,6 +205,11 @@ tr_verify_worker::~tr_verify_worker()
|
|||
}
|
||||
}
|
||||
|
||||
void tr_verify_worker::set_sleep_per_seconds_during_verify(std::chrono::milliseconds const sleep_per_seconds_during_verify)
|
||||
{
|
||||
sleep_per_seconds_during_verify_ = sleep_per_seconds_during_verify;
|
||||
}
|
||||
|
||||
int tr_verify_worker::Node::compare(Node const& that) const noexcept
|
||||
{
|
||||
// prefer higher-priority torrents
|
||||
|
|
|
@ -47,6 +47,13 @@ public:
|
|||
|
||||
void remove(tr_sha1_digest_t const& info_hash);
|
||||
|
||||
void set_sleep_per_seconds_during_verify(std::chrono::milliseconds sleep_per_seconds_during_verify);
|
||||
|
||||
[[nodiscard]] constexpr auto sleep_per_seconds_during_verify() const noexcept
|
||||
{
|
||||
return sleep_per_seconds_during_verify_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Node
|
||||
{
|
||||
|
@ -72,7 +79,10 @@ private:
|
|||
tr_priority_t priority_;
|
||||
};
|
||||
|
||||
static void verify_torrent(Mediator& verify_mediator, std::atomic<bool> const& abort_flag);
|
||||
static void verify_torrent(
|
||||
Mediator& verify_mediator,
|
||||
std::atomic<bool> const& abort_flag,
|
||||
std::chrono::milliseconds sleep_per_seconds_during_verify);
|
||||
|
||||
void verify_thread_func();
|
||||
|
||||
|
@ -85,4 +95,6 @@ private:
|
|||
|
||||
std::atomic<bool> stop_current_ = false;
|
||||
std::condition_variable stop_current_cv_;
|
||||
|
||||
std::chrono::milliseconds sleep_per_seconds_during_verify_;
|
||||
};
|
||||
|
|
|
@ -454,3 +454,45 @@ TEST_F(SettingsTest, canSavePreferredTransport)
|
|||
EXPECT_TRUE(tr_variantDictFindStrView(&var, Key, &val));
|
||||
EXPECT_EQ("tcp", val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadSleepPerSecondsDuringVerify)
|
||||
{
|
||||
static auto constexpr Key = TR_KEY_sleep_per_seconds_during_verify;
|
||||
auto constexpr ExpectedValue = 90ms;
|
||||
|
||||
auto settings = std::make_unique<tr_session_settings>();
|
||||
auto const default_value = settings->sleep_per_seconds_during_verify;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ExpectedValue.count());
|
||||
settings->load(var);
|
||||
EXPECT_EQ(ExpectedValue, settings->sleep_per_seconds_during_verify);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session_settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, 90);
|
||||
settings->load(var);
|
||||
EXPECT_EQ(ExpectedValue, settings->sleep_per_seconds_during_verify);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canSaveSleepPerSecondsDuringVerify)
|
||||
{
|
||||
static auto constexpr Key = TR_KEY_sleep_per_seconds_during_verify;
|
||||
static auto constexpr ExpectedValue = 90ms;
|
||||
|
||||
auto settings = tr_session_settings{};
|
||||
auto const default_value = settings.sleep_per_seconds_during_verify;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 100);
|
||||
settings.sleep_per_seconds_during_verify = ExpectedValue;
|
||||
var = settings.settings();
|
||||
|
||||
int64_t val_raw;
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, Key, &val_raw));
|
||||
EXPECT_EQ(ExpectedValue, std::chrono::milliseconds{ val_raw });
|
||||
}
|
Loading…
Reference in New Issue
Block a user