refactor(ops): decouple task-per-tx drivers from SubOperationTracker (#1454 phase 3c)#3889
Conversation
…1454 phase 3c) Switch all 4 is_sub_operation guard sites (p2p_protoc.rs, node.rs x2, subscribe.rs) from op_manager.is_sub_operation() (DashMap lookup) to Transaction::is_sub_operation() (structural parent field check). This is a superset — correct for both legacy and task-per-tx children. Remove expect_and_register_sub_operation calls from PUT and GET task-per-tx drivers (op_ctx_task.rs). These drivers await or fire-and-forget children directly and never use the parking-lot mechanism. The tracker registration was only needed for the DashMap guard, which is now replaced by the structural check. Latent fix: async non-blocking subscribe children (track_parent=false) were never registered in the tracker, so op_manager.is_sub_operation() returned false — they'd incorrectly try to notify a nonexistent client waiter at LocalSubscribeComplete. The structural check fixes this. SubOperationTracker itself stays alive for legacy PUT/GET relay paths that still use the parking-lot. Full deletion deferred until relay migration (#3883) completes.
Rule Review: Clean refactor with one minor docstring inaccuracyRules checked: WarningsNone. Info
Summary of changes reviewed: The PR correctly replaces four Rule review against |
Problem
After Phases 3a (#3843) and 3b (#3884) migrated client-initiated PUT and GET to task-per-tx drivers, both drivers still registered subscribe children with
SubOperationTrackerviaexpect_and_register_sub_operation. This was only needed soop_manager.is_sub_operation(tx)(a DashMap lookup) returned true at 4 guard sites that prevent spurious client notifications. The task-per-tx drivers never used the tracker's parking-lot mechanism — they await or fire-and-forget children directly.Additionally, async non-blocking subscribe children (
track_parent=false) were never registered in the tracker, soop_manager.is_sub_operation()returnedfalsefor them — they'd incorrectly try to notify a nonexistent client waiter atLocalSubscribeComplete.Solution
Switch all 4
is_sub_operationguard sites fromop_manager.is_sub_operation(tx)(DashMap lookup onSubOperationTracker.parent_of) totx.is_sub_operation()(structural check:Transaction.parent.is_some(), set at creation bynew_child_of). This is a superset — correct for both legacy and task-per-tx children, and fixes the latent bug for async non-blocking children.Then remove
expect_and_register_sub_operationcalls from PUT and GET task-per-tx drivers, making them fully independent ofSubOperationTracker.SubOperationTrackeritself stays alive — legacy PUT/GET relay paths still use the parking-lot mechanism. Full deletion deferred until relay migration (#3883) completes.Guard sites changed
p2p_protoc.rs:2061LocalSubscribeCompletesilent-absorbnode.rs:552node.rs:646subscribe.rs:932handle_abort— sub-op vs standalone abort routingTesting
cargo clippy -- -D warnings— cleancargo test -p freenet— 2380 tests pass (4 pre-existing macOS connectivity failures unrelated)Fixes
Partial progress on #1454 (Phase 3c)