Skip to content

Release typespec-ts emitter singleton state after $onEmit#4787

Merged
xirzec merged 1 commit into
mainfrom
xirzec-ts-emitter-release-singleton-state
Jul 7, 2026
Merged

Release typespec-ts emitter singleton state after $onEmit#4787
xirzec merged 1 commit into
mainfrom
xirzec-ts-emitter-release-singleton-state

Conversation

@xirzec

@xirzec xirzec commented Jun 30, 2026

Copy link
Copy Markdown
Member

What

Clears the emitter's process-wide singleton state at the end of $onEmit:

  • ContextManager.clearContexts() — drops the stored EmitContext/Program, TCGC SdkContext, ts-morph Project, binder, etc.
  • resetSdkTypesState() — clears the module-level emitQueue / flattenPropertyModelMap / pagedModelsKeptPublic collections.

Why

These live at module scope, so after an emit they keep the most recently emitted program graph reachable until the next emit overwrites them. Clearing right after the emit finishes lets that memory be collected sooner when many emits run in one process (test suites, watch mode).

Scope / honesty

This is bounded-to-one-program hygiene — it is not a fix for an unbounded leak. The actual unbounded leak behind #4536 is upstream in the compiler's experimental mutators (seen cache pins every mutated program's type-graph for the process lifetime) and is tracked separately in microsoft/typespec#11120. This PR is just good housekeeping on the typespec-ts side and is independent of that fix.

Changeset is marked internal accordingly.

Related: #4536, microsoft/typespec#11120

Clear the context manager and module-level SDK-type collections at the end
of $onEmit so the previously emitted program graph can be collected between
emits instead of lingering until the next emit overwrites it. This is
bounded-to-one-program hygiene, not a fix for an unbounded leak (the real
leak tracked in microsoft/typespec#11120 is upstream in the compiler's
experimental mutators).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@azure-sdk-automation

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @azure-tools/typespec-ts
Show changes

@azure-tools/typespec-ts - internal ✏️

Proactively release the emitter's process-wide singleton state at the end of $onEmit as a hygiene measure. The context manager and the module-level SDK-type collections otherwise keep the most recently emitted program graph reachable until the next emit overwrites them; clearing them after each emit lets that memory be collected sooner when many emits run in one process (test suites, watch mode). This is bounded-to-one-program cleanup and is not a fix for any unbounded leak.

@pkg-pr-new

pkg-pr-new Bot commented Jun 30, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-ts@4787

commit: 8c14b0f

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

@github-actions

Copy link
Copy Markdown
Contributor

⚡ Benchmark Results

⚠️ 36 metric(s) regressed above the +5% threshold:

Metric Baseline Current Change
total 🔴 678.0ms 🔴 1.05s +55.5% 🔴
loader 🟢 191.6ms 🟡 328.0ms +71.2% 🔴
resolver 🟢 19.4ms 🟢 40.9ms +111.2% 🔴
checker 🟡 213.9ms 🟡 375.8ms +75.6% 🔴
validation 🟢 47.6ms 🟢 87.0ms +82.5% 🔴
 ↳ validation/@azure-tools/typespec-azure-core 🟢 7.0ms 🟡 13.3ms +90.6% 🔴
 ↳ validation/@typespec/http 🟢 6.4ms 🟡 16.2ms +152.9% 🔴
 ↳ validation/@typespec/versioning 🔴 31.3ms 🔴 51.7ms +65.2% 🔴
 ↳ validation/compiler 🟢 1.8ms 🟢 4.0ms +119.7% 🔴
linter 🟢 149.6ms 🟡 222.9ms +49.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 6.3ms 🟢 8.5ms +35.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 0.9ms 🟢 2.0ms +117.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 20.4ms 🔴 27.9ms +36.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 2.0ms 🟢 3.1ms +52.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 21.7ms 🔴 29.2ms +34.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 25.4ms 🔴 34.6ms +36.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 5.4ms 🟢 8.2ms +50.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 23.6ms 🔴 34.5ms +46.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 5.9ms 🟢 7.9ms +34.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🟢 4.7ms 🔴 21.6ms +355.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟢 4.6ms 🟡 12.4ms +168.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 1.6ms 🟢 4.6ms +181.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 10.5ms 🟡 17.1ms +63.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 5.3ms 🟢 9.2ms +75.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 14.6ms 🔴 20.7ms +42.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 21.5ms 🔴 31.8ms +48.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 4.0ms 🟢 5.3ms +33.0% 🔴
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 1.2ms 🟢 2.3ms +100.0% 🔴
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 0.3ms 🟢 1.7ms +510.0% 🔴
emit 🔴 5.59s 🔴 6.13s +9.7% 🔴
 ↳ emit/@azure-tools/typespec-autorest 🟢 84.4ms 🟢 129.2ms +53.1% 🔴
 ↳ emit/@azure-tools/typespec-python 🔴 2.15s 🔴 2.27s +5.8% 🔴
 ↳ emit/@typespec/http-client-js 🔴 470.0ms 🔴 586.2ms +24.7% 🔴
 ↳ emit/@typespec/openapi3 🟢 76.7ms 🟢 112.1ms +46.0% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 66.9ms 🟢 97.4ms +45.5% 🔴
 ↳ emit/@typespec/openapi3/write 🟢 9.6ms 🟢 14.3ms +49.5% 🔴
Full details – comparing 856b84e vs baseline rolling-baseline-8eefeb1-0592536 (rolling baseline (20 main runs))
Metric Baseline Current Change
total 🔴 678.0ms 🔴 1.05s +55.5% 🔴
loader 🟢 191.6ms 🟡 328.0ms +71.2% 🔴
resolver 🟢 19.4ms 🟢 40.9ms +111.2% 🔴
checker 🟡 213.9ms 🟡 375.8ms +75.6% 🔴
validation 🟢 47.6ms 🟢 87.0ms +82.5% 🔴
 ↳ validation/@azure-tools/typespec-azure-core 🟢 7.0ms 🟡 13.3ms +90.6% 🔴
 ↳ validation/@typespec/http 🟢 6.4ms 🟡 16.2ms +152.9% 🔴
 ↳ validation/@typespec/rest 🟢 0.7ms 🟢 1.7ms +148.5%
 ↳ validation/@typespec/versioning 🔴 31.3ms 🔴 51.7ms +65.2% 🔴
 ↳ validation/compiler 🟢 1.8ms 🟢 4.0ms +119.7% 🔴
linter 🟢 149.6ms 🟡 222.9ms +49.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.0ms 🟢 0.1ms +382.6%
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.2ms 🟢 0.6ms +140.6%
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 6.3ms 🟢 8.5ms +35.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 0.7ms 🟢 1.5ms +119.7%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.1ms 🟢 0.2ms +133.2%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 0.9ms 🟢 2.0ms +117.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 0.7ms 🟢 1.4ms +114.0%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.2ms 🟢 0.4ms +113.4%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.3ms 🟢 0.5ms +69.9%
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.3ms 🟢 0.8ms +151.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.3ms 🟢 0.7ms +163.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 0.3ms 🟢 1.0ms +216.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.1ms 🟢 0.3ms +366.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.1ms 🟢 0.3ms +161.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.1ms 🟢 0.2ms +67.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.6ms 🟢 0.8ms +44.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.5ms 🟢 0.8ms +84.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 20.4ms 🔴 27.9ms +36.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 1.2ms 🟢 2.0ms +68.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.1ms 🟢 0.2ms +163.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.3ms 🟢 0.4ms +61.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 1.3ms 🟢 2.0ms +60.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 2.0ms 🟢 2.3ms +14.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 2.0ms 🟢 3.1ms +52.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 21.7ms 🔴 29.2ms +34.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 25.4ms 🔴 34.6ms +36.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.0ms 🟢 0.1ms +314.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 5.4ms 🟢 8.2ms +50.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.2ms 🟢 0.4ms +98.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.1ms 🟢 0.2ms +189.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.2ms 🟢 0.4ms +76.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.4ms 🟢 0.8ms +103.0%
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.2ms 🟢 0.4ms +91.3%
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.3ms 🟢 0.5ms +47.5%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.0ms 🟢 0.1ms +467.0%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 23.6ms 🔴 34.5ms +46.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.3ms 🟢 0.8ms +123.7%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.3ms 🟢 0.5ms +68.2%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 5.9ms 🟢 7.9ms +34.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.1ms 🟢 0.3ms +100.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🟢 4.7ms 🔴 21.6ms +355.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations 🟢 0.0ms 🟢 0.3ms +1319.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟢 4.6ms 🟡 12.4ms +168.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.1ms 🟢 0.2ms +134.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.1ms +97.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 1.6ms 🟢 4.6ms +181.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 10.5ms 🟡 17.1ms +63.4% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.4ms 🟢 0.7ms +78.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 0.6ms 🟢 1.5ms +157.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.0ms 🟢 0.2ms +651.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.2ms 🟢 0.4ms +73.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.1ms 🟢 0.4ms +190.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.0ms 🟢 0.1ms +399.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.1ms 🟢 0.2ms +87.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.1ms 🟢 0.3ms +174.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.1ms 🟢 0.2ms +321.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.3ms 🟢 0.5ms +99.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.0ms 🟢 0.1ms +661.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.2ms 🟢 0.5ms +193.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 5.3ms 🟢 9.2ms +75.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.3ms 🟢 0.8ms +137.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.2ms 🟢 0.4ms +93.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.1ms 🟢 0.4ms +238.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.1ms 🟢 0.2ms +154.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.2ms 🟢 0.4ms +162.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.0ms 🟢 0.1ms +1078.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 14.6ms 🔴 20.7ms +42.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.0ms 🟢 0.1ms +384.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 0.3ms 🟢 1.0ms +195.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.1ms 🟢 0.3ms +93.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props 🟢 0.1ms 🟢 0.3ms +303.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.2ms 🟢 0.5ms +131.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 21.5ms 🔴 31.8ms +48.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.2ms 🟢 0.4ms +161.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.2ms 🟢 0.4ms +167.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 4.0ms 🟢 5.3ms +33.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.4ms 🟢 0.7ms +75.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.0ms 🟢 0.3ms +560.9%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 1.2ms 🟢 2.3ms +100.0% 🔴
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 0.3ms 🟢 1.7ms +510.0% 🔴
emit 🔴 5.59s 🔴 6.13s +9.7% 🔴
 ↳ emit/@Azure-Tools 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@azure-tools/typespec-autorest 🟢 84.4ms 🟢 129.2ms +53.1% 🔴
 ↳ emit/@azure-tools/typespec-python 🔴 2.15s 🔴 2.27s +5.8% 🔴
 ↳ emit/@typespec 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@typespec/http-client-js 🔴 470.0ms 🔴 586.2ms +24.7% 🔴
 ↳ emit/@typespec/openapi3 🟢 76.7ms 🟢 112.1ms +46.0% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 66.9ms 🟢 97.4ms +45.5% 🔴
 ↳ emit/@typespec/openapi3/write 🟢 9.6ms 🟢 14.3ms +49.5% 🔴

Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)

@xirzec xirzec added this pull request to the merge queue Jul 6, 2026
Merged via the queue into main with commit 4df8556 Jul 7, 2026
32 checks passed
@xirzec xirzec deleted the xirzec-ts-emitter-release-singleton-state branch July 7, 2026 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:typescript Issues for @azure-tools/typespec-ts emitter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants