diff --git a/common/changes/@itwin/core-transformer/transformer-handle-large-models_2022-02-22-18-07.json b/common/changes/@itwin/core-transformer/transformer-handle-large-models_2022-02-22-18-07.json new file mode 100644 index 00000000000..78f58038cff --- /dev/null +++ b/common/changes/@itwin/core-transformer/transformer-handle-large-models_2022-02-22-18-07.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/core-transformer", + "comment": "mitigate memory leak in large model processing", + "type": "none" + } + ], + "packageName": "@itwin/core-transformer" +} \ No newline at end of file diff --git a/core/transformer/src/IModelExporter.ts b/core/transformer/src/IModelExporter.ts index e2a32339811..b62591d6a42 100644 --- a/core/transformer/src/IModelExporter.ts +++ b/core/transformer/src/IModelExporter.ts @@ -475,6 +475,7 @@ export class IModelExporter { } while (DbResult.BE_SQLITE_ROW === statement.step()) { await this.exportElement(statement.getValue(0).getId()); + await new Promise(setImmediate); // workaround for: https://github.com/nodejs/node-addon-api/issues/1140 } }); } @@ -638,6 +639,7 @@ export class IModelExporter { const relInstanceId: Id64String = statement.getValue(0).getId(); const relProps: RelationshipProps = this.sourceDb.relationships.getInstanceProps(baseRelClassFullName, relInstanceId); await this.exportRelationship(relProps.classFullName, relInstanceId); // must call exportRelationship using the actual classFullName, not baseRelClassFullName + await new Promise(setImmediate); // workaround for: https://github.com/nodejs/node-addon-api/issues/1140 } }); } diff --git a/core/transformer/src/IModelTransformer.ts b/core/transformer/src/IModelTransformer.ts index 27a3af9583b..b8929d807b3 100644 --- a/core/transformer/src/IModelTransformer.ts +++ b/core/transformer/src/IModelTransformer.ts @@ -709,7 +709,7 @@ export class IModelTransformer extends IModelExportHandler { } const aspectDeleteIds: Id64String[] = []; const sql = `SELECT ECInstanceId,Identifier,JsonProperties FROM ${ExternalSourceAspect.classFullName} aspect WHERE aspect.Scope.Id=:scopeId AND aspect.Kind=:kind`; - this.targetDb.withPreparedStatement(sql, (statement: ECSqlStatement): void => { + await this.targetDb.withPreparedStatement(sql, async (statement: ECSqlStatement) => { statement.bindId("scopeId", this.targetScopeElementId); statement.bindString("kind", ExternalSourceAspect.Kind.Relationship); while (DbResult.BE_SQLITE_ROW === statement.step()) { @@ -722,6 +722,7 @@ export class IModelTransformer extends IModelExportHandler { } aspectDeleteIds.push(statement.getValue(0).getId()); } + await new Promise(setImmediate); // workaround for: https://github.com/nodejs/node-addon-api/issues/1140 } }); this.targetDb.elements.deleteAspect(aspectDeleteIds);