mirror of
https://github.com/transmission/transmission
synced 2024-12-21 23:32:35 +00:00
feat: configurable client reqq
(#7030)
* chore: housekeeping * refactor: raise client reqq value * feat: allow configuring client reqq value * feat: expose reqq config in RPC * test: add new key * code review: distinguish client vs peer * docs: fix new config name --------- Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
parent
b0a6bf964c
commit
62240393ed
7 changed files with 39 additions and 14 deletions
|
@ -101,6 +101,7 @@ Here is a sample of the three basic types: respectively Boolean, Number and Stri
|
|||
* **peer-limit-global:** Number (default = 200)
|
||||
* **peer-limit-per-torrent:** Number (default = 50)
|
||||
* **peer-socket-tos:** String (default = "le") Set the [DiffServ](https://en.wikipedia.org/wiki/Differentiated_services) parameter for outgoing packets. Allowed values are lowercase DSCP names. See the `tr_tos_t` class from `libtransmission/net.h` for the exact list of possible values.
|
||||
* **reqq:** Number (default = 2000) The number of outstanding block requests a peer is allowed to queue in the client. The higher this number, the higher the max possible upload speed towards each peer.
|
||||
|
||||
#### Peer Port
|
||||
* **peer-port:** Number (default = 51413)
|
||||
|
|
|
@ -554,6 +554,7 @@ Response arguments: `path`, `name`, and `id`, holding the torrent ID integer
|
|||
| `queue-stalled-enabled` | boolean | whether or not to consider idle torrents as stalled
|
||||
| `queue-stalled-minutes` | number | torrents that are idle for N minuets aren't counted toward seed-queue-size or download-queue-size
|
||||
| `rename-partial-files` | boolean | true means append `.part` to incomplete files
|
||||
| `reqq` | number | the number of outstanding block requests a peer is allowed to queue in the client
|
||||
| `rpc-version-minimum` | number | the minimum RPC API version supported
|
||||
| `rpc-version-semver` | string | the current RPC API version in a [semver](https://semver.org)-compatible string
|
||||
| `rpc-version` | number | the current RPC API version
|
||||
|
|
|
@ -905,7 +905,7 @@ EXIT:
|
|||
// ---
|
||||
|
||||
// number of bad pieces a peer is allowed to send before we ban them
|
||||
static auto constexpr MaxBadPiecesPerPeer = 5;
|
||||
static auto constexpr MaxBadPiecesPerPeer = 5U;
|
||||
|
||||
// how long we'll let requests we've made linger before we cancel them
|
||||
static auto constexpr RequestTtlSecs = 90;
|
||||
|
|
|
@ -178,7 +178,7 @@ auto constexpr KeepaliveIntervalSecs = time_t{ 100 };
|
|||
|
||||
auto constexpr MetadataReqQ = size_t{ 64U };
|
||||
|
||||
auto constexpr ReqQ = 512;
|
||||
auto constexpr PeerReqQDefault = 500U;
|
||||
|
||||
// when we're making requests from another peer,
|
||||
// batch them together to send enough requests to
|
||||
|
@ -571,6 +571,11 @@ private:
|
|||
|
||||
void update_block_requests();
|
||||
|
||||
[[nodiscard]] constexpr auto client_reqq() const noexcept
|
||||
{
|
||||
return session->reqq();
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
[[nodiscard]] std::optional<int64_t> pop_next_metadata_request()
|
||||
|
@ -702,7 +707,7 @@ private:
|
|||
|
||||
// if the peer supports the Extension Protocol in BEP 10 and
|
||||
// supplied a reqq argument, it's stored here.
|
||||
std::optional<size_t> reqq_;
|
||||
std::optional<size_t> peer_reqq_;
|
||||
|
||||
std::unique_ptr<libtransmission::Timer> pex_timer_;
|
||||
|
||||
|
@ -1131,9 +1136,8 @@ void tr_peerMsgsImpl::send_ltep_handshake()
|
|||
|
||||
// https://www.bittorrent.org/beps/bep_0010.html
|
||||
// An integer, the number of outstanding request messages this
|
||||
// client supports without dropping any. The default in in
|
||||
// libtorrent is 250.
|
||||
tr_variantDictAddInt(&val, TR_KEY_reqq, ReqQ);
|
||||
// client supports without dropping any.
|
||||
tr_variantDictAddInt(&val, TR_KEY_reqq, client_reqq());
|
||||
|
||||
// https://www.bittorrent.org/beps/bep_0010.html
|
||||
// A string containing the compact representation of the ip address this peer sees
|
||||
|
@ -1289,7 +1293,7 @@ void tr_peerMsgsImpl::parse_ltep_handshake(MessageReader& payload)
|
|||
/* get peer's maximum request queue size */
|
||||
if (auto reqq_in = int64_t{}; tr_variantDictFindInt(&*var, TR_KEY_reqq, &reqq_in))
|
||||
{
|
||||
reqq_ = reqq_in;
|
||||
peer_reqq_ = reqq_in;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1994,7 +1998,7 @@ bool tr_peerMsgsImpl::is_valid_request(peer_request const& req) const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (std::size(peer_requested_) >= ReqQ)
|
||||
if (std::size(peer_requested_) >= client_reqq())
|
||||
{
|
||||
logtrace(this, "rejecting request ... reqq is full");
|
||||
return false;
|
||||
|
@ -2045,7 +2049,7 @@ size_t tr_peerMsgsImpl::max_available_reqs() const
|
|||
static auto constexpr Floor = size_t{ 32 };
|
||||
static size_t constexpr Seconds = RequestBufSecs;
|
||||
size_t const estimated_blocks_in_period = (rate.base_quantity() * Seconds) / tr_block_info::BlockSize;
|
||||
auto const ceil = reqq_.value_or(250);
|
||||
auto const ceil = peer_reqq_.value_or(PeerReqQDefault);
|
||||
|
||||
return std::clamp(estimated_blocks_in_period, Floor, ceil);
|
||||
}
|
||||
|
|
|
@ -1695,6 +1695,11 @@ char const* sessionSet(tr_session* session, tr_variant::Map const& args_in, tr_v
|
|||
tr_sessionSetPeerLimitPerTorrent(session, *val);
|
||||
}
|
||||
|
||||
if (auto const val = args_in.value_if<int64_t>(TR_KEY_reqq); val && val > 0)
|
||||
{
|
||||
session->set_reqq(*val);
|
||||
}
|
||||
|
||||
if (auto const val = args_in.value_if<bool>(TR_KEY_pex_enabled))
|
||||
{
|
||||
tr_sessionSetPexEnabled(session, *val);
|
||||
|
@ -1955,6 +1960,7 @@ char const* sessionStats(tr_session* session, tr_variant::Map const& /*args_in*/
|
|||
case TR_KEY_queue_stalled_enabled: return session.queueStalledEnabled();
|
||||
case TR_KEY_queue_stalled_minutes: return session.queueStalledMinutes();
|
||||
case TR_KEY_rename_partial_files: return session.isIncompleteFileNamingEnabled();
|
||||
case TR_KEY_reqq: return session.reqq();
|
||||
case TR_KEY_rpc_version: return RpcVersion;
|
||||
case TR_KEY_rpc_version_minimum: return RpcVersionMin;
|
||||
case TR_KEY_rpc_version_semver: return RpcVersionSemver;
|
||||
|
|
|
@ -398,6 +398,7 @@ public:
|
|||
size_t peer_limit_global = TR_DEFAULT_PEER_LIMIT_GLOBAL;
|
||||
size_t peer_limit_per_torrent = TR_DEFAULT_PEER_LIMIT_TORRENT;
|
||||
size_t queue_stalled_minutes = 30U;
|
||||
size_t reqq = 2000U;
|
||||
size_t seed_queue_size = 10U;
|
||||
size_t speed_limit_down = 100U;
|
||||
size_t speed_limit_up = 100U;
|
||||
|
@ -465,6 +466,7 @@ public:
|
|||
{ TR_KEY_ratio_limit, &ratio_limit },
|
||||
{ TR_KEY_ratio_limit_enabled, &ratio_limit_enabled },
|
||||
{ TR_KEY_rename_partial_files, &is_incomplete_file_naming_enabled },
|
||||
{ TR_KEY_reqq, &reqq },
|
||||
{ TR_KEY_scrape_paused_torrents_enabled, &should_scrape_paused_torrents },
|
||||
{ TR_KEY_script_torrent_added_enabled, &script_torrent_added_enabled },
|
||||
{ TR_KEY_script_torrent_added_filename, &script_torrent_added_filename },
|
||||
|
@ -693,6 +695,16 @@ public:
|
|||
return settings().peer_limit_per_torrent;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto reqq() const noexcept
|
||||
{
|
||||
return settings().reqq;
|
||||
}
|
||||
|
||||
constexpr void set_reqq(size_t reqq) noexcept
|
||||
{
|
||||
settings_.reqq = reqq;
|
||||
}
|
||||
|
||||
// bandwidth
|
||||
|
||||
[[nodiscard]] tr_bandwidth& getBandwidthGroup(std::string_view name);
|
||||
|
|
|
@ -168,7 +168,7 @@ TEST_F(RpcTest, sessionGet)
|
|||
EXPECT_TRUE(tr_variantDictFindDict(&response, TR_KEY_arguments, &args));
|
||||
|
||||
// what we expected
|
||||
auto const expected_keys = std::array<tr_quark, 59>{
|
||||
static auto constexpr ExpectedKeys = std::array{
|
||||
TR_KEY_alt_speed_down,
|
||||
TR_KEY_alt_speed_enabled,
|
||||
TR_KEY_alt_speed_time_begin,
|
||||
|
@ -204,6 +204,7 @@ TEST_F(RpcTest, sessionGet)
|
|||
TR_KEY_queue_stalled_enabled,
|
||||
TR_KEY_queue_stalled_minutes,
|
||||
TR_KEY_rename_partial_files,
|
||||
TR_KEY_reqq,
|
||||
TR_KEY_rpc_version,
|
||||
TR_KEY_rpc_version_minimum,
|
||||
TR_KEY_rpc_version_semver,
|
||||
|
@ -242,8 +243,8 @@ TEST_F(RpcTest, sessionGet)
|
|||
|
||||
auto missing_keys = std::vector<tr_quark>{};
|
||||
std::set_difference(
|
||||
std::begin(expected_keys),
|
||||
std::end(expected_keys),
|
||||
std::begin(ExpectedKeys),
|
||||
std::end(ExpectedKeys),
|
||||
std::begin(actual_keys),
|
||||
std::end(actual_keys),
|
||||
std::inserter(missing_keys, std::begin(missing_keys)));
|
||||
|
@ -253,8 +254,8 @@ TEST_F(RpcTest, sessionGet)
|
|||
std::set_difference(
|
||||
std::begin(actual_keys),
|
||||
std::end(actual_keys),
|
||||
std::begin(expected_keys),
|
||||
std::end(expected_keys),
|
||||
std::begin(ExpectedKeys),
|
||||
std::end(ExpectedKeys),
|
||||
std::inserter(unexpected_keys, std::begin(unexpected_keys)));
|
||||
EXPECT_EQ(decltype(unexpected_keys){}, unexpected_keys);
|
||||
|
||||
|
|
Loading…
Reference in a new issue