From 2d17c265cadf5d69c0ed2ea6f3b5a85b8b4c8562 Mon Sep 17 00:00:00 2001 From: Cats Juice Date: Thu, 12 Jun 2025 12:35:14 +0800 Subject: [PATCH] fix: memory leak due to missing unsubscribe (#12777) - unsubscribe `Signal` not correctly - missing un-subscription for `Livedata.signal` ## Summary by CodeRabbit - **Bug Fixes** - Improved resource management to ensure subscriptions are properly cleaned up, reducing potential memory leaks and improving overall app stability. --- blocksuite/affine/widgets/toolbar/src/toolbar.ts | 4 +--- packages/common/infra/src/livedata/livedata.ts | 8 +++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/blocksuite/affine/widgets/toolbar/src/toolbar.ts b/blocksuite/affine/widgets/toolbar/src/toolbar.ts index e1c5143f4e..fe002876da 100644 --- a/blocksuite/affine/widgets/toolbar/src/toolbar.ts +++ b/blocksuite/affine/widgets/toolbar/src/toolbar.ts @@ -541,9 +541,7 @@ export class AffineToolbarWidget extends WidgetComponent { ); }); - return () => { - subscription.unsubscribe(); - }; + disposables.add(subscription); }) ); diff --git a/packages/common/infra/src/livedata/livedata.ts b/packages/common/infra/src/livedata/livedata.ts index b3ddb5d38e..384b9c8c91 100644 --- a/packages/common/infra/src/livedata/livedata.ts +++ b/packages/common/infra/src/livedata/livedata.ts @@ -250,6 +250,9 @@ export class LiveData private isPoisoned = false; private poisonedError: PoisonedError | null = null; + private _signal: Signal | undefined; + private _signalSubscription: Subscription | undefined; + constructor( initialValue: T, upstream: @@ -302,12 +305,10 @@ export class LiveData this.next(v); } - private _signal: Signal | undefined; - get signal(): ReadonlySignal { if (!this._signal) { this._signal = signal(this.value); - this.subscribe(v => { + this._signalSubscription = this.subscribe(v => { // oxlint-disable-next-line no-non-null-assertion this._signal!.value = v; }); @@ -464,6 +465,7 @@ export class LiveData this.ops$.complete(); this.raw$.complete(); this.upstreamSubscription?.unsubscribe(); + this._signalSubscription?.unsubscribe(); } /**