Fix/max open files settings - #3145
Open
xirvik wants to merge 4 commits into
Open
Conversation
network.max_open_files.set has been an inert stub since 0.16.16: it logs a deprecation warning and discards the value. The file and HTTP socket limits belong to libtorrent's socket manager instead. Remapping the setter to system.sockets.<category>.max_alloc.set is not enough on its own. max_alloc is a ceiling that can only lower the allocation, and nothing takes effect until the socket manager recomputes it. Measured against 0.16.19 with a 10240 file allocation, max_alloc.set(20000) leaves max_size at 10240 even after a recompute, while min_alloc.set(20000) raises it. Raising the limit is the only thing the setting is used for. Send min_alloc and max_alloc together so the allocation lands on exactly the requested value in either direction, then emit system.sockets.adjust_alloc once per settings batch, only when one of the two settings was present. The commands share the request with the rest of the batch, so a rejected allocation surfaces as a fault rather than the dialog reverting silently. Restricted to 0.16.19 and later. Earlier versions abort on an over-budget adjust_alloc, and the client cannot check the budget beforehand because its reserve and min_generic terms are not exposed over RPC. 0.16.19 reports a regular XMLRPC fault instead. Older versions keep their current behaviour. Fixes Novik#3140
get_max_open_http read system.sockets.http.max_alloc, the ceiling rather than the allocation in effect, so the settings dialog showed a number orders of magnitude above the real limit: 1000000 against an effective 512. Read system.sockets.http.max_size instead, which is what max_open_files already does through network.max_open_files. That command has existed since 0.16.15, so every version loading this alias file has it. The socket manager stages min_alloc/max_alloc until adjust_alloc recomputes the allocation, and a rejected recompute keeps the staged values. One over-budget entry therefore also broke every later recompute, including saves of unrelated settings that only touched the other category. Read the bounds in effect before replacing them and put them back when the recompute is refused. libtorrent exposes no revert of its own, but the staged bounds are readable, and restoring a state that was valid moments earlier is accepted; a restore that is somehow still refused is logged rather than passed over silently. Applied to the httprpc path, where sequential control flow makes the read/write/restore ordering natural. The client path builds its batch up front and has no hook on the fault path, so it keeps the simpler behaviour.
4 tasks
A refused settings save told the user nothing. The response carried a fixed "Warning: XMLRPC call is failed." while the reason -- which allocation would not fit, and by how much -- reached only the server log. With a low open-file limit the effect is that a raise is quietly clamped back to the old value and the fix reads as not working, when rtorrent had in fact explained itself. rXMLRPCRequest now keeps the faultString it already detects, and the failure response sends it in place of the generic warning. That is the path the client already reports through, so nothing in the request layer changes. A fault nested in a system.multicall array is matched too, which is where a refused allocation shows up. Every settings write is also recorded, one line per setting, with the value in effect before and after and whether it was taken: setsettings: max_open_files requested=70000 from=20000 to=20000 rejected setsettings: batch rejected (adjust_allocation: total + min_generic + 8 reserve exceeds max_open : 71152 + 12288 + 8 > 76000) The "to" side is read back rather than assumed, since a refused batch can leave a value clamped or untouched, and that difference is the whole question when a limit does not end up where it was asked to. Settings without a symmetric getter -- the hash_* trio, which stopped being readable in 0.9.0, and dht, reported through dht.statistics -- are logged as unavailable rather than guessed at or dropped.
"XMLRPC call is failed" and "Maybe, rTorrent is down?" are not idiomatic English. Reword both, keeping the distinction between no reply at all and a call that was answered with a fault.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
●
network.max_open_files.sethas been an inert stub since 0.16.16 — it logs adeprecation warning and discards the value. The file and HTTP socket limits belong
to libtorrent's socket manager instead, so the settings field silently does nothing.
Remapping the setter to
system.sockets.<category>.max_alloc.setis not enough onits own.
max_allocis a ceiling that can only lower the allocation, and nothingtakes effect until the socket manager recomputes. Measured against 0.16.19 with a
10240 file allocation:
max_alloc.set(20000)leavesmax_sizeat 10240 even aftera recompute, while
min_alloc.set(20000)raises it. Raising the limit is the onlything the setting is used for.
This sends
min_allocandmax_alloctogether so the allocation lands on exactlythe requested value in either direction, then emits
system.sockets.adjust_alloconce per settings batch, only when one of the two settings was present.
Restricted to 0.16.19 and later. Earlier versions abort on an over-budget
adjust_alloc, and the client cannot check the budget beforehand because itsreserveandmin_genericterms are not exposed over RPC. 0.16.19 reports aregular XMLRPC fault instead. Older versions keep their current behaviour.
Two related problems are fixed alongside it:
get_max_open_httpreadsystem.sockets.http.max_alloc, the ceiling rather thanthe allocation in effect, so the dialog reported 1000000 against an effective 512.
It now reads
system.sockets.http.max_size, matching howmax_open_filesreadsnetwork.max_open_files. That command has existed since 0.16.15.The socket manager stages
min_alloc/max_allocuntiladjust_allocruns, and arejected recompute keeps the staged values — so one over-budget entry also broke
every later recompute, including saves of unrelated settings. The bounds in effect
are now read before being replaced and put back if the recompute is refused.
libtorrent has no revert call of its own, but the bounds are readable and restoring
a state valid moments earlier is accepted; a restore that is itself refused is
logged rather than passed over. This applies to the httprpc path; the client path
builds its batch up front and has no hook on the fault path, so it keeps the
simpler behaviour.
Verified end to end against 0.16.19: setting the field to 20000 raises
system.sockets.files.max_sizeandnetwork.max_open_filesfrom 10240 to 20000 andthe dialog reads back 20000; an over-budget value returns a clean fault with the
bounds restored, the process alive, and a subsequent valid save on another field
succeeding where it previously failed.
Adds
tests/js/setsettings.spec.jscovering command construction on both sides ofthe version gate and the read-back mapping.
Fixes #3140