Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Let OTLP log and trace exporters leave no timer pending while idle

Abierto
#10,234 0 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@effect-bot ya está trabajando en esto.

Desde el 31/10/2026.

  • #10235 de @schutzelaars — abierto

Evaluación

Este issue todavía no se ha evaluado.

Descripción

What is the problem this feature would solve?

OtlpExporter.make re-arms its export timer forever, even with nothing buffered (OtlpExporter.ts#L264-L269). So an idle program always has a timer pending: every 1 s for logs and every 5 s for traces. Some runtimes stay in memory while a timer is pending. Cloudflare Durable Objects, for example, can't hibernate and keep billing duration (docs).

OpenTelemetry JS avoids this. Its span and log processors start the timer on the first record and stop once the buffer is empty (BatchSpanProcessorBase.ts#L230-L253, BatchLogRecordProcessorBase.ts#L333-L368).

Prior discussion: effect-smol#2107 and #6641 added Flusher, so a workerd integration can flush per event instead of waiting for an interval. That covers work inside an event. This covers the exporter's own timer, which keeps an idle Durable Object from hibernating even when every event flushes.

Repro ([email protected], same code on main): npm i [email protected] tsx@4, then npx tsx repro.ts.

import { Effect, Layer } from "effect"
import { FetchHttpClient } from "effect/http"
import { OtlpLogger, OtlpSerialization, OtlpTracer } from "effect/observability"

const resource = { serviceName: "idle" }
const exporters = Layer.mergeAll(
  OtlpLogger.layer({ url: "http://localhost:4318/v1/logs", resource }),
  OtlpTracer.layer({ url: "http://localhost:4318/v1/traces", resource })
).pipe(Layer.provide(OtlpSerialization.layerJson), Layer.provide(FetchHttpClient.layer))

// Nothing is ever logged or traced.
Effect.runFork(Effect.never.pipe(Effect.provide(exporters)))

setTimeout(() => {
  const timers = process.getActiveResourcesInfo().filter((name) => name === "Timeout").length
  console.log("timers pending after 3 s idle:", timers - 1) // minus this one
  process.exit(0)
}, 3000)
  • Expected: timers pending after 3 s idle: 0.
  • Actual: timers pending after 3 s idle: 2, one per exporter, for as long as the scope is open.
What is the feature you are proposing to solve the problem?

Match OpenTelemetry JS: a log or trace exporter starts its interval when a record reaches an empty buffer, and stops once the buffer is empty again. Records still go out within one interval, and exports stay one at a time. Metrics keep their fixed interval, as OpenTelemetry's periodic reader does. So the combined Otlp layers still tick unless metrics use metricsExportInterval: Duration.infinity with Flusher.flush. I have a PR ready.

What alternatives have you considered?
  • exportInterval: Duration.infinity plus Flusher.flush. This works today, but records then wait for a manual flush and are lost if the runtime drops the instance first.
  • An option. No one benefits from a timer that exports nothing.

Related: alchemy-run/alchemy#2878. We hit this exporting from Cloudflare Durable Objects built with Alchemy.

I investigated this with an AI coding agent, Claude Code. The agent read the Effect sources, wrote the repro and the patch, and ran them and Effect's checks. I reviewed the analysis before filing.

Lenguaje dominante
TypeScript
Estrellas
16.7k
Forks
808
Merge medio
10 h 15 min
PR fusionados (30 d)
845

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Effect-TS/effect

Todos los issues de Effect-TS/effect

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.