From 1279bd9f7a46ea34f406a30d617730cbeac7169c Mon Sep 17 00:00:00 2001 From: Xirvik Date: Sun, 3 May 2026 20:38:35 +0000 Subject: [PATCH] Move d.save_full_session to run after user-registered inserted_new handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously d.save_full_session was inside the 1_prepare handler for event.download.inserted_new. Since 0.16.6 moved session saving to a separate thread, save_full_download() snapshots the bencode synchronously when called and queues the prebuilt streams for async write. If user-registered handlers (e.g. seedingtime plugin's addtime setter running d.set_custom=addtime) sort lexicographically AFTER 1_prepare, they modify the bencode AFTER the snapshot has already been taken. The first on-disk .rtorrent then lacks those custom fields. The next periodic resume save catches up, but if rtorrent restarts before that, the data is lost — manifesting as blank Finished/SeedingTime columns in ruTorrent. Fix: split the inserted_new key into two — 1_prepare keeps view visibility setup, ~_save_full runs d.save_full_session last (~ prefix is ASCII 0x7E, sorts after all alphanumerics, matching the existing ~_delete_tied precedent on event.download.erased). The snapshot then includes any custom fields written by user handlers. --- src/main.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main.cc b/src/main.cc index c797f193..8d86e74d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -209,7 +209,14 @@ main(int argc, char** argv) { "method.insert = event.download.hash_queued,multi|rlookup|static\n" "method.set_key = event.download.inserted, 1_send_scrape, ((d.tracker.send_scrape,30))\n" - "method.set_key = event.download.inserted_new, 1_prepare, {(branch,((d.state)),((view.set_visible,started)),((view.set_visible,stopped)) ),(d.save_full_session)}\n" + "method.set_key = event.download.inserted_new, 1_prepare, {(branch,((d.state)),((view.set_visible,started)),((view.set_visible,stopped)) )}\n" + // d.save_full_session runs LAST (~ prefix is ASCII 0x7E, sorts after all alphanumerics, + // matching the existing ~_delete_tied precedent on event.download.erased) so the on-disk + // snapshot includes custom fields written by other inserted_new handlers (addtime, + // seedingtime, etc.). Was previously inside 1_prepare alongside view setup, which + // snapshotted bencode before later handlers ran, so d.set_custom=addtime did not reach + // .rtorrent until the next periodic resume save — a window where rtorrent restart lost them. + "method.set_key = event.download.inserted_new, ~_save_full, ((d.save_full_session))\n" "method.set_key = event.download.inserted_session, 1_prepare, {(branch,((d.state)),((view.set_visible,started)),((view.set_visible,stopped)) )}\n" "method.set_key = event.download.inserted, 1_prioritize_toc, \"branch=file.prioritize_toc=,{\\\"f.multicall=(file.prioritize_toc.first),f.prioritize_first.enable=\\\",\\\"f.multicall=(file.prioritize_toc.last),f.prioritize_last.enable=\\\",d.update_priorities=}\"\n"