Pārlūkot izejas kodu

fix(cordis): dispose only the registered logger exporter

turtle1999 3 nedēļas atpakaļ
vecāks
revīzija
ac2f890291

+ 4 - 0
packages/boot/app-boot/tests/app-boot.spec.ts

@@ -780,13 +780,17 @@ describe('boot', () => {
     const config = join(dir, 'cordis.yml')
     writeFileSync(config, '[]\n')
     let exporters = 0
+    const messages: unknown[][] = []
     const ctx = await boot(NAME, config, undefined, (host) => {
+      host.logger.exporter({ levels: { default: 2 }, export: ({ args }) => { messages.push(args) } })
       exporters = host.logger.exporters.size
       host.logger.info('startup information')
       host.logger.warn('startup warning')
     })
     try {
       expect(ctx.logger.exporters.size).toBe(exporters - 1)
+      ctx.logger.warn('warning after startup')
+      expect(messages).toEqual([['startup information'], ['startup warning'], ['warning after startup']])
     } finally {
       await ctx.fiber.dispose()
     }

+ 2 - 0
vendor/README.md

@@ -52,6 +52,8 @@ Keep this log exhaustive — every divergence from upstream must be listed.
 
 20. **`loader/src/config/entry.ts` fiber identity**: stores the original fiber from the registry result’s context instead of its PromiseLike wrapper. Configuration updates and service notifications therefore mutate the same lifecycle state; updating a provider and consumer together cannot strand the consumer in `PENDING`. Covered by `packages/boot/hmr/tests/modules.spec.ts` and the built profile reload regression in `apps/cli/tests/built-bin.e2e.ts`.
 
+21. **`cordis/src/logger.ts` exporter disposal**: each disposer retains its registration id, so removing an earlier exporter cannot delete a later console or telemetry exporter. Covered by startup collector cleanup in `packages/boot/app-boot/tests/app-boot.spec.ts` and disabled-feedback output in `packages/session/session-telemetry-otel/tests/loader-composition.e2e.ts`.
+
 ## Sync procedure
 
 To update a vendored package from upstream:

+ 3 - 2
vendor/cordis/src/logger.ts

@@ -231,8 +231,9 @@ export class LoggerService {
    */
   exporter(exporter: Exporter) {
     return this.ctx.effect(() => {
-      this.exporters.set(++this._snExporter, exporter)
-      return () => this.exporters.delete(this._snExporter)
+      const id = ++this._snExporter
+      this.exporters.set(id, exporter)
+      return () => this.exporters.delete(id)
     }, 'ctx.logger.exporter()')
   }