fix(mem-leak): running_swap never shrinks#2301
Conversation
|
Why is this PR blocked? I can see CI builds are green and commit history doesn't depend on any common commits from other PRs. |
Nope it depends on history from #2280, no extra commits are showing up here since I am trying to merge into |
mm2src/mm2_main/src/lp_swap.rs
Outdated
| pub fn running_swaps_num(ctx: &MmArc) -> u64 { | ||
| let swap_ctx = SwapsContext::from_ctx(ctx).unwrap(); | ||
| let swaps = swap_ctx.running_swaps.lock().unwrap(); | ||
| swaps.iter().fold(0, |total, (swap, _)| match swap.upgrade() { | ||
| Some(_) => total + 1, | ||
| None => total, | ||
| }) | ||
| let count = swap_ctx.running_swaps.lock().unwrap().len(); | ||
| count as u64 | ||
| } |
There was a problem hiding this comment.
let change the return type to usize instead of u64
mm2src/mm2_main/src/lp_swap.rs
Outdated
| for (swap, _) in swaps.values() { | ||
| if coins.contains(&swap.maker_coin().to_string()) || coins.contains(&swap.taker_coin().to_string()) { | ||
| uuids.push(*swap.uuid()) |
There was a problem hiding this comment.
you can use uuid.extend and filter_map to avoid for loop and push
I am not sure what is the purpose of this PR then 🤔 |
|
Basically this PR looks good for me: it removes finished or aborted swaps from the running_swaps list. |
this field was convereted to a hashmap instead of a vector for easy access to the swap also we now manually delete the swap from running swaps when the swap is finished (memory leak fix). as a consequence to manuallly deleting the swap from running_swaps, we can now store them as arcs instead of weakrefs, which simplifies a lot of .upgrade calls.
b02fced to
0890de8
Compare
|
re-wrote the fix on top of dev. it's not blocked anymore by the original PR from |
|
|
||
| struct SwapsContext { | ||
| running_swaps: Mutex<Vec<Weak<dyn AtomicSwap>>>, | ||
| running_swaps: Mutex<HashMap<Uuid, Arc<dyn AtomicSwap>>>, |
There was a problem hiding this comment.
I wonder if we intentionally chose a weak reference instead of Arc as it might avoid cyclic references (similar to how it's done for MmArc with MmWeak in coins) 🤔
There was a problem hiding this comment.
I suspect this could be the reason of https://github.com/KomodoPlatform/komodo-defi-framework/actions/runs/12666194163/job/35297118282?pr=2301#step:9:895 failure.
There was a problem hiding this comment.
not that i can trivially find the AtomicSwap pointing back to it self (points to mmctx tho: https://github.com/KomodoPlatform/komodo-defi-framework/blob/0a9410258c7bf58e78d26b33b7a0ffb749c7ba16/mm2src/mm2_main/src/lp_swap/maker_swap.rs#L213)
you see, such questions are really hard to answer in such a codebase and require digging xD
it's much easier/managable to avoid the arc/weak model and use our abortable systems to make sure cyclic refs aren't problematic.
i went for arc here tho since we already manually remove the swap after it finishes or after stopping it. since we drop the thing manually we don't need to complicate it with weak refs.
There was a problem hiding this comment.
It's worth to test that change (by using test_mm2_stops_immediately test) to make sure that's not the case.
a4e7c75 to
fbd5e9f
Compare
|
Force pushed to re-trigger CI. |
THERE ARE NO RUNNING SWAPS
theoretically we don't need to clear it on native targets since the executable will terminate even without clearing, but for wasm the story isn't exactly the same, i presume
mm2src/mm2_main/src/lp_swap.rs
Outdated
| @@ -655,13 +655,9 @@ pub fn get_locked_amount(ctx: &MmArc, coin: &str) -> MmNumber { | |||
| } | |||
|
|
|||
| /// Get number of currently running swaps | |||
There was a problem hiding this comment.
fix this doc comment
also consider clearing the running swap on mmctx destructor/stop method instead.
There was a problem hiding this comment.
also i wanted to clear the swaps in MmCtx::stop instead since that's how we destruct MmCtx. but that won't work because we have no access to SwapsContext data type.
| pub fn clear_running_swaps(ctx: &MmArc) { | ||
| let swap_ctx = SwapsContext::from_ctx(ctx).unwrap(); | ||
| let swaps = swap_ctx.running_swaps.lock().unwrap(); | ||
| swaps.iter().fold(0, |total, swap| match swap.upgrade() { | ||
| Some(_) => total + 1, | ||
| None => total, | ||
| }) | ||
| swap_ctx.running_swaps.lock().unwrap().clear(); |
There was a problem hiding this comment.
Does clearing the map stops swap processes?
There was a problem hiding this comment.
yup. the store of running_swaps stores the swaps (AtomicSwap object) along with the abort handles (which will trigger on Drop) they are running on.
messed things, look at: #2301 (comment)
There was a problem hiding this comment.
Can you please mention that on the code?
There was a problem hiding this comment.
it's already in the doc comment. or u mean somewhere else?
There was a problem hiding this comment.
Ah didn't see that. I was referring to caller side but it's fine
There was a problem hiding this comment.
big ooops:
yup. the store of running_swaps stores the swaps (AtomicSwap object) along with the abort handles (which will trigger on Drop) they are running on.
this is completely wrong. this feat is in another PR. i mixed things up.
no, clearing the running swaps will not stop these swaps. (though could be stopped via other means, e.g. abort_all from a bigger subsystem).
There was a problem hiding this comment.
Ok that is def. worth to mention that on the line.
There was a problem hiding this comment.
I tried this code, looks like clear_running_swaps fn is needed to clear swaps_ctx in MmCtx to allow to release ctx so stop_and_wait_for_ctx_is_dropped fn can finish (used in wasm tests).
(this note to memorise)
There was a problem hiding this comment.
updated the doc comment accordingly till the other PR that stores the abort handle lands in.
|
I am okay with this PR. |
64a0012
Seems the changes to the code were reverted. So I approved |
* dev: fix(hash-types): remove panic, enforce fixed-size arrays (GLEECBTC#2279) fix(ARRR): store unconfirmed change output (GLEECBTC#2276) feat(tendermint): staking/delegation (GLEECBTC#2322) chore(deps): `timed-map` migration (GLEECBTC#2247) fix(mem-leak): `running_swap` never shrinks (GLEECBTC#2301) chore(dep-bump): libp2p (GLEECBTC#2326) refactor(build script): rewrite the main build script (GLEECBTC#2319)
* dev: fix(hash-types): remove panic, enforce fixed-size arrays (GLEECBTC#2279) fix(ARRR): store unconfirmed change output (GLEECBTC#2276) feat(tendermint): staking/delegation (GLEECBTC#2322) chore(deps): `timed-map` migration (GLEECBTC#2247) fix(mem-leak): `running_swap` never shrinks (GLEECBTC#2301) chore(dep-bump): libp2p (GLEECBTC#2326) refactor(build script): rewrite the main build script (GLEECBTC#2319)
* dev: fix(derive_key_from_path): check length of current_key_material (#2356) chore(release): bump mm2 version to 2.4.0-beta (#2346) fix(tests): add additional testnet sepolia nodes to test code (#2358) fix(swaps): maintain legacy compatibility for negotiation messages (#2353) refactor(SwapOps): impl defaults for protocol specific swapops fns (#2354) feat(tpu-v2): provide swap protocol versioning (#2324) feat(wallet): add change mnemonic password rpc (#2317) fix(tpu-v2): fix tpu-v2 wait for payment spend and extract secret (#2261) feat(tendermint): unstaking/undelegation (#2330) fix(utxo-withdraw): get hw ctx only when `PrivKeyPolicy` is trezor (#2333) feat(event-streaming): API-driven subscription management (#2172) fix(hash-types): remove panic, enforce fixed-size arrays (#2279) fix(ARRR): store unconfirmed change output (#2276) feat(tendermint): staking/delegation (#2322) chore(deps): `timed-map` migration (#2247) fix(mem-leak): `running_swap` never shrinks (#2301) chore(dep-bump): libp2p (#2326) refactor(build script): rewrite the main build script (#2319)
* dev: fix(derive_key_from_path): check length of current_key_material (#2356) chore(release): bump mm2 version to 2.4.0-beta (#2346) fix(tests): add additional testnet sepolia nodes to test code (#2358) fix(swaps): maintain legacy compatibility for negotiation messages (#2353) refactor(SwapOps): impl defaults for protocol specific swapops fns (#2354) feat(tpu-v2): provide swap protocol versioning (#2324) feat(wallet): add change mnemonic password rpc (#2317) fix(tpu-v2): fix tpu-v2 wait for payment spend and extract secret (#2261) feat(tendermint): unstaking/undelegation (#2330) fix(utxo-withdraw): get hw ctx only when `PrivKeyPolicy` is trezor (#2333) feat(event-streaming): API-driven subscription management (#2172) fix(hash-types): remove panic, enforce fixed-size arrays (#2279) fix(ARRR): store unconfirmed change output (#2276) feat(tendermint): staking/delegation (#2322) chore(deps): `timed-map` migration (#2247) fix(mem-leak): `running_swap` never shrinks (#2301) chore(dep-bump): libp2p (#2326) refactor(build script): rewrite the main build script (#2319)
* dev: (24 commits) fix(eth-tpu): remove state from funding validation (GLEECBTC#2334) improvement(rpc-server): rpc server dynamic port allocation (GLEECBTC#2342) fix(tests): fix or ignore unstable tests (GLEECBTC#2365) fix(fs): make `filter_files_by_extension` return only files (GLEECBTC#2364) fix(derive_key_from_path): check length of current_key_material (GLEECBTC#2356) chore(release): bump mm2 version to 2.4.0-beta (GLEECBTC#2346) fix(tests): add additional testnet sepolia nodes to test code (GLEECBTC#2358) fix(swaps): maintain legacy compatibility for negotiation messages (GLEECBTC#2353) refactor(SwapOps): impl defaults for protocol specific swapops fns (GLEECBTC#2354) feat(tpu-v2): provide swap protocol versioning (GLEECBTC#2324) feat(wallet): add change mnemonic password rpc (GLEECBTC#2317) fix(tpu-v2): fix tpu-v2 wait for payment spend and extract secret (GLEECBTC#2261) feat(tendermint): unstaking/undelegation (GLEECBTC#2330) fix(utxo-withdraw): get hw ctx only when `PrivKeyPolicy` is trezor (GLEECBTC#2333) feat(event-streaming): API-driven subscription management (GLEECBTC#2172) fix(hash-types): remove panic, enforce fixed-size arrays (GLEECBTC#2279) fix(ARRR): store unconfirmed change output (GLEECBTC#2276) feat(tendermint): staking/delegation (GLEECBTC#2322) chore(deps): `timed-map` migration (GLEECBTC#2247) fix(mem-leak): `running_swap` never shrinks (GLEECBTC#2301) ...
this field was convereted to a hashmap instead of a vector for easy access to the swap. also we now manually delete the swap from running swaps when the swap is finished~/inturepted~ (memory leak fix). as a consequence to manuallly deleting the swap from running_swaps, we can now store them as arcs instead of weakrefs, which simplifies a lot of
.upgrade()calls.blocked on its base #2280re-fixed on top ofdevinstead