fix(instance): ensure proper disposal of current unit (#6254)

Co-authored-by: hexf00 <hexf00@gmail.com>
This commit is contained in:
siam
2025-12-09 20:33:05 +08:00
committed by GitHub
parent fc254b9e93
commit c407cdf456
5 changed files with 40 additions and 5 deletions
@@ -27,6 +27,7 @@ import { Workbook } from '../../sheets/workbook';
import { SlideDataModel } from '../../slides/slide-model';
import { FOCUSING_DOC, FOCUSING_SHEET, FOCUSING_SLIDE, FOCUSING_UNIT } from '../context/context';
import { IContextService } from '../context/context.service';
import { ILogService } from '../log/log.service';
// eslint-disable-next-line ts/no-explicit-any
export type UnitCtor = new (...args: any[]) => UnitModel;
@@ -107,7 +108,8 @@ export class UniverInstanceService extends Disposable implements IUniverInstance
constructor(
@Inject(Injector) private readonly _injector: Injector,
@IContextService private readonly _contextService: IContextService
@IContextService private readonly _contextService: IContextService,
@Inject(ILogService) private readonly _logService: ILogService
) {
super();
}
@@ -118,6 +120,8 @@ export class UniverInstanceService extends Disposable implements IUniverInstance
this._focused$.complete();
this._currentUnits$.complete();
this._unitAdded$.complete();
this._currentUnits.forEach((unit) => unit?.dispose());
this._currentUnits.clear();
this._unitsByType.clear();
}
@@ -186,6 +190,7 @@ export class UniverInstanceService extends Disposable implements IUniverInstance
* @param unit The unit to be added.
*/
__addUnit(unit: UnitModel, options?: ICreateUnitOptions): void {
this._logService.debug(`[UniverInstanceService]: Adding unit with id ${unit.getUnitId()}`);
const type = unit.type;
if (!this._unitsByType.has(type)) {
@@ -296,12 +301,17 @@ export class UniverInstanceService extends Disposable implements IUniverInstance
}
disposeUnit(unitId: string): boolean {
this._logService.debug(`[UniverInstanceService]: Disposing unit with id ${unitId}`);
const result = this._getUnitById(unitId);
if (!result) return false;
if (!result) {
this._logService.debug(`[UniverInstanceService]: No unit found with id ${unitId}`);
return false;
}
const [unit, type] = result;
const units = this._unitsByType.get(type)!;
const index = units.indexOf(unit);
units.splice(index, 1);
this._tryResetCurrentOnRemoval(unitId, type);
@@ -309,6 +319,8 @@ export class UniverInstanceService extends Disposable implements IUniverInstance
this._unitDisposed$.next(unit);
unit.dispose();
return true;
}
+4
View File
@@ -117,6 +117,10 @@ export class Workbook extends UnitModel<IWorkbookData, UniverInstanceType.UNIVER
this._sheetDisposed$.complete();
this._activeSheet$.complete();
this._name$.complete();
Promise.resolve().then(() => {
this._worksheets.clear();
});
}
/**
@@ -85,6 +85,7 @@ export class WebWorkerRemoteInstanceService implements IRemoteInstanceService {
type: UniverInstanceType;
snapshot: IWorkbookData;
}): Promise<boolean> {
this._logService.debug(`[WebWorkerRemoteInstanceService]: Creating instance with id ${params.unitID}`);
const { type, snapshot } = params;
try {
switch (type) {
@@ -106,6 +107,7 @@ export class WebWorkerRemoteInstanceService implements IRemoteInstanceService {
}
async disposeInstance(params: { unitID: string }): Promise<boolean> {
this._logService.debug(`[WebWorkerRemoteInstanceService]: Disposing instance with id ${params.unitID}`);
return this._univerInstanceService.disposeUnit(params.unitID);
}
+7 -3
View File
@@ -316,7 +316,8 @@ export class ChannelClient extends RxDisposable implements IChannelClient {
}
private _onMessage(response: IRPCResponse): void {
switch (response.type) {
const { type: responseType, seq } = response;
switch (responseType) {
case ResponseType.INITIALIZE:
this._initialized.next(true);
break;
@@ -324,9 +325,12 @@ export class ChannelClient extends RxDisposable implements IChannelClient {
case ResponseType.CALL_FAILURE:
case ResponseType.SUBSCRIBE_NEXT:
case ResponseType.SUBSCRIBE_COMPLETE:
case ResponseType.SUBSCRIBE_ERROR:
this._pendingRequests.get(response.seq)?.handle(response);
case ResponseType.SUBSCRIBE_ERROR: {
const { _pendingRequests } = this;
_pendingRequests.get(seq)?.handle(response);
responseType !== ResponseType.SUBSCRIBE_NEXT && _pendingRequests.delete(seq);
break;
}
}
}
}
@@ -460,11 +460,24 @@ export class TableManager extends Disposable {
}
deleteUnitId(unitId: string) {
const unitMap = this._tableMap.get(unitId);
if (unitMap) {
unitMap.forEach((table) => table.dispose());
}
this._tableMap.delete(unitId);
}
override dispose() {
super.dispose();
this._tableAdd$.complete();
this._tableDelete$.complete();
this._tableNameChanged$.complete();
this._tableRangeChanged$.complete();
this._tableThemeChanged$.complete();
this._tableFilterChanged$.complete();
this._tableInitStatus.complete();
this._tableMap.forEach((unitMap) => {
unitMap.forEach((table) => table.dispose());
unitMap.clear();