Skip to content

Commit 702688a

Browse files
feat: add destroy() to MdkNode to fix 402 zombie node race condition (#30)
* feat: add destroy() method to MdkNode for explicit cleanup On serverless platforms (Vercel/Lambda), MdkNode's inner Rust Node and its tokio runtime survive after getInvoice() returns because V8 GC is non-deterministic. When the agent pays a 402 invoice instantly (<1s), the webhook handler creates a second MdkNode for the same wallet while the first is still alive. The zombie's reconnection loop steals the LSP peer connection from the new node, preventing the JIT channel from being established and causing "retries exhausted" payment failures. In normal checkout this doesn't happen because the human delay (5-30s) gives GC time to collect the old node before the webhook fires. destroy() wraps the inner Node in Option<Node>, allowing JS callers to explicitly drop the Rust Node and its tokio runtime immediately after invoice creation, eliminating the race condition. * style: fix cargo fmt
1 parent c81f35b commit 702688a

2 files changed

Lines changed: 99 additions & 49 deletions

File tree

index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ export interface NodeChannel {
7171
}
7272
export declare class MdkNode {
7373
constructor(options: MdkNodeOptions)
74+
/**
75+
* Destroy the node, dropping the inner Rust Node and its tokio runtime immediately.
76+
* This prevents zombie processes on serverless platforms where GC is non-deterministic.
77+
* After calling destroy(), any further method calls on this node will panic.
78+
*/
79+
destroy(): void
7480
getNodeId(): string
7581
start(): void
7682
stop(): void

0 commit comments

Comments
 (0)