Skip to content

Conversation

@pichlermarc
Copy link
Member

Which problem is this PR solving?

See #5916

This PR partially addresses #5916. unrefTimer() does reference Node.js types and leaks them even if you're not working on a Node.js project. This PR fixes this instance by widening the type to accept { unref(): unknown } | number instead of just NodeJS.Timer, getting rid of the platform specific implementations in the process.

Since the utility function does not really do much, this PR also deprecates it. It also in-lines any existing usages so that we can easily remove it in the next major version.

This is pretty difficult to test since it does not fully solve the problem yet: otperformance does still leak the Node.js types - I'll fix this in a follow-up.

In the meantime, you can verify that this actually not referencing Node.js types anymore by following these steps:

  • npm ci
  • npm run compile
  • cd packages
  • grep -r '/// <reference types="node"'

You can then verify that timer-util.d.ts is not listed in the output anymore:

./opentelemetry-resources/build/esm/detectors/platform/node/machine-id/execAsync.d.ts:/// <reference types="node" /> ./opentelemetry-resources/build/esnext/detectors/platform/node/machine-id/execAsync.d.ts:/// <reference types="node" /> ./opentelemetry-resources/build/src/detectors/platform/node/machine-id/execAsync.d.ts:/// <reference types="node" /> ./opentelemetry-exporter-jaeger/build/src/types.d.ts:/// <reference types="node" /> ./opentelemetry-core/build/esm/platform/node/performance.d.ts:/// <reference types="node" /> ./opentelemetry-core/build/esnext/platform/node/performance.d.ts:/// <reference types="node" /> ./opentelemetry-core/build/src/platform/node/performance.d.ts:/// <reference types="node" /> 

(Note: the occurrence in @opentelemetry/resources should not cause any issues, since it's not part of the public API, @opentelemetry/exporter-jaeger is not supported in the browser)

@pichlermarc pichlermarc requested a review from a team as a code owner October 6, 2025 11:52
@codecov
Copy link

codecov bot commented Oct 6, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.24%. Comparing base (77c48d2) to head (1b4d530).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@ ## main #5986 +/- ## ========================================== + Coverage 95.23% 95.24% +0.01%  ========================================== Files 315 315 Lines 8598 8602 +4 Branches 1791 1795 +4 ========================================== + Hits 8188 8193 +5  + Misses 410 409 -1 
Files with missing lines Coverage Δ
...sdk-logs/src/export/BatchLogRecordProcessorBase.ts 93.61% <100.00%> (+0.06%) ⬆️
...ckages/opentelemetry-core/src/common/timer-util.ts 100.00% <100.00%> (ø)
...dk-trace-base/src/export/BatchSpanProcessorBase.ts 95.16% <100.00%> (+0.03%) ⬆️
...etrics/src/export/PeriodicExportingMetricReader.ts 98.24% <100.00%> (+0.03%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

private _finishedLogRecords: SdkLogRecord[] = [];
private _timer: NodeJS.Timeout | undefined;
private _timer: NodeJS.Timeout | number | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are removing NodeJS.Timer type in src/common/timer-util.ts but this private property still holds NodeJS.Timeout. I've checked the type signature and saw that NodeJS.Timeout extends NodeJS.Timer. Should we replace the type here as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be safe to keep. The private property's type gets erased in the final type definition. As a consequence, /// <reference types="node" /> does not end up in the BatchLogRecordProcessor.d.ts :)

import type { BufferConfig } from '../types'; import type { SdkLogRecord } from './SdkLogRecord'; import type { LogRecordExporter } from './LogRecordExporter'; import type { LogRecordProcessor } from '../LogRecordProcessor'; export declare abstract class BatchLogRecordProcessorBase<T extends BufferConfig> implements LogRecordProcessor { private readonly _exporter; private readonly _maxExportBatchSize; private readonly _maxQueueSize; private readonly _scheduledDelayMillis; private readonly _exportTimeoutMillis; private _finishedLogRecords; private _timer; private _shutdownOnce; constructor(_exporter: LogRecordExporter, config?: T); onEmit(logRecord: SdkLogRecord): void; forceFlush(): Promise<void>; shutdown(): Promise<void>; private _shutdown; /** Add a LogRecord in the buffer. */ private _addToBuffer; /**  * Send all LogRecords to the exporter respecting the batch size limit  * This function is used only on forceFlush or shutdown,  * for all other cases _flush should be used  * */ private _flushAll; private _flushOneBatch; private _maybeStartTimer; private _clearTimer; private _export; protected abstract onShutdown(): void; } //# sourceMappingURL=BatchLogRecordProcessorBase.d.ts.map
* @deprecated please copy this code to your implementation instead, this function will be removed in the next major version of this package.
* @param timer
*/
export function unrefTimer(timer: { unref(): unknown } | number): void {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if it is worth to keep this and make the argument a Refable, like https://nodejs.org/api/process.html#processunrefmayberefable, so that we can reduce the repetitiveness.

Copy link
Member

@legendecas legendecas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deprecating the util functions in the core package also makes sense

@pichlermarc
Copy link
Member Author

Deprecating the util functions in the core package also makes sense

Thanks, I think I'll leave it like this then 🙂 By deprecating and eventually removing it we can eventually reduce the amount of public APIs that end-users don't need to use directly, so I think the duplication is worthwhile in the end. 🙂

@pichlermarc pichlermarc added this pull request to the merge queue Oct 8, 2025
Merged via the queue into open-telemetry:main with commit f8450cf Oct 8, 2025
25 checks passed
@pichlermarc pichlermarc deleted the fix/unref-timer-type-leak branch October 8, 2025 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3 participants