Skip to content

Commit 51662e3

Browse files
committed
Revert "fix: fix 3. actually working"
This reverts commit 1fc9b25.
1 parent 3f0d3f5 commit 51662e3

6 files changed

Lines changed: 7 additions & 216 deletions

File tree

packages/cloudflare/src/sdk.ts

Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,13 @@ import { setupOpenTelemetryTracer } from './opentelemetry/tracer';
2020
import { makeCloudflareTransport } from './transport';
2121
import { defaultStackParser } from './vendor/stacktrace';
2222

23-
// Cache for default integrations to avoid recreating them on every request.
24-
// Key is a string representation of options that affect integration creation.
25-
// This significantly reduces memory allocation under high load.
26-
let _cachedDefaultIntegrations: Integration[] | undefined;
27-
let _cachedIntegrationKey: string | undefined;
28-
2923
/** Get the default integrations for the Cloudflare SDK. */
3024
export function getDefaultIntegrations(options: CloudflareOptions): Integration[] {
3125
const sendDefaultPii = options.sendDefaultPii ?? false;
32-
const enableDedupe = options.enableDedupe !== false;
33-
34-
// Create a cache key based on options that affect integration creation
35-
const cacheKey = `${sendDefaultPii}:${enableDedupe}`;
36-
37-
// Return cached integrations if the options match
38-
if (_cachedDefaultIntegrations && _cachedIntegrationKey === cacheKey) {
39-
return _cachedDefaultIntegrations;
40-
}
41-
42-
const integrations = [
26+
return [
4327
// The Dedupe integration should not be used in workflows because we want to
4428
// capture all step failures, even if they are the same error.
45-
...(enableDedupe ? [dedupeIntegration()] : []),
29+
...(options.enableDedupe === false ? [] : [dedupeIntegration()]),
4630
// TODO(v11): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`
4731
// eslint-disable-next-line deprecation/deprecation
4832
inboundFiltersIntegration(),
@@ -55,29 +39,6 @@ export function getDefaultIntegrations(options: CloudflareOptions): Integration[
5539
requestDataIntegration(sendDefaultPii ? undefined : { include: { cookies: false } }),
5640
consoleIntegration(),
5741
];
58-
59-
// Cache for subsequent requests
60-
_cachedDefaultIntegrations = integrations;
61-
_cachedIntegrationKey = cacheKey;
62-
63-
return integrations;
64-
}
65-
66-
// Cache for processed integrations and stack parser to avoid reprocessing on every request
67-
let _cachedProcessedIntegrations: Integration[] | undefined;
68-
let _cachedStackParser: ReturnType<typeof stackParserFromStackParserOptions> | undefined;
69-
let _openTelemetryTracerSetup = false;
70-
71-
/**
72-
* Resets the SDK cache. This is primarily used for testing purposes.
73-
* @internal
74-
*/
75-
export function _INTERNAL_resetSdkCache(): void {
76-
_cachedDefaultIntegrations = undefined;
77-
_cachedIntegrationKey = undefined;
78-
_cachedProcessedIntegrations = undefined;
79-
_cachedStackParser = undefined;
80-
_openTelemetryTracerSetup = false;
8142
}
8243

8344
/**
@@ -91,22 +52,10 @@ export function init(options: CloudflareOptions): CloudflareClient | undefined {
9152
const flushLock = options.ctx ? makeFlushLock(options.ctx) : undefined;
9253
delete options.ctx;
9354

94-
// Cache processed integrations - only recompute if user provides custom integrations
95-
if (!_cachedProcessedIntegrations && !options.integrations) {
96-
_cachedProcessedIntegrations = getIntegrationsToSetup(options);
97-
}
98-
99-
// Cache stack parser
100-
if (!_cachedStackParser && !options.stackParser) {
101-
_cachedStackParser = stackParserFromStackParserOptions(defaultStackParser);
102-
}
103-
10455
const clientOptions: CloudflareClientOptions = {
10556
...options,
106-
stackParser: options.stackParser
107-
? stackParserFromStackParserOptions(options.stackParser)
108-
: (_cachedStackParser as ReturnType<typeof stackParserFromStackParserOptions>),
109-
integrations: options.integrations ? getIntegrationsToSetup(options) : (_cachedProcessedIntegrations as Integration[]),
57+
stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),
58+
integrations: getIntegrationsToSetup(options),
11059
transport: options.transport || makeCloudflareTransport,
11160
flushLock,
11261
};
@@ -118,9 +67,8 @@ export function init(options: CloudflareOptions): CloudflareClient | undefined {
11867
* HOWEVER, big caveat: This does not handle custom context handling, it will always work off the current scope.
11968
* This should be good enough for many, but not all integrations.
12069
*/
121-
if (!options.skipOpenTelemetrySetup && !_openTelemetryTracerSetup) {
70+
if (!options.skipOpenTelemetrySetup) {
12271
setupOpenTelemetryTracer();
123-
_openTelemetryTracerSetup = true;
12472
}
12573

12674
return initAndBind(CloudflareClient, clientOptions) as CloudflareClient;

packages/cloudflare/test/handler.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { CloudflareClient } from '../src/client';
1515
import { withSentry } from '../src/handler';
1616
import { markAsInstrumented } from '../src/instrument';
1717
import * as HonoIntegration from '../src/integrations/hono';
18-
import { resetSdk } from './testUtils';
1918

2019
// Custom type for hono-like apps (cloudflare handlers) that include errorHandler and onError
2120
type HonoLikeApp<Env = unknown, QueueHandlerMessage = unknown, CfHostMetadata = unknown> = ExportedHandler<
@@ -44,7 +43,6 @@ function addDelayedWaitUntil(context: ExecutionContext) {
4443
describe('withSentry', () => {
4544
beforeEach(() => {
4645
vi.clearAllMocks();
47-
resetSdk();
4846
});
4947

5048
describe('fetch handler', () => {

packages/cloudflare/test/request.test.ts

Lines changed: 0 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { setAsyncLocalStorageAsyncContextStrategy } from '../src/async';
99
import type { CloudflareOptions } from '../src/client';
1010
import { CloudflareClient } from '../src/client';
1111
import { wrapRequestHandler } from '../src/request';
12-
import { resetSdk } from './testUtils';
1312

1413
const MOCK_OPTIONS: CloudflareOptions = {
1514
dsn: 'https://public@dsn.ingest.sentry.io/1337',
@@ -26,7 +25,6 @@ describe('withSentry', () => {
2625

2726
beforeEach(() => {
2827
vi.clearAllMocks();
29-
resetSdk();
3028
});
3129

3230
test('passes through the response from the handler', async () => {
@@ -159,10 +157,6 @@ describe('withSentry', () => {
159157
{
160158
options: {
161159
...MOCK_OPTIONS,
162-
// Set tracesSampleRate to enable the full path that adds request info
163-
// (when tracesSampleRate is undefined/0, the fast path is used which
164-
// only adds request info on errors for performance)
165-
tracesSampleRate: 1,
166160
beforeSend(event) {
167161
sentryEvent = event;
168162
return null;
@@ -375,105 +369,6 @@ describe('withSentry', () => {
375369
});
376370
});
377371
});
378-
379-
describe('client disposal', () => {
380-
test('disposes of the client after the request completes to allow garbage collection', async () => {
381-
// Create context with a waitUntil that captures promises
382-
const waitUntilPromises: Promise<unknown>[] = [];
383-
const context = {
384-
waitUntil: vi.fn((promise: Promise<unknown>) => {
385-
waitUntilPromises.push(promise);
386-
}),
387-
passThroughOnException: vi.fn(),
388-
} as unknown as ExecutionContext;
389-
390-
let capturedClient: CloudflareClient | undefined;
391-
await wrapRequestHandler(
392-
{
393-
options: {
394-
...MOCK_OPTIONS,
395-
tracesSampleRate: 1, // Enable tracing to test full path
396-
},
397-
request: new Request('https://example.com'),
398-
context,
399-
},
400-
() => {
401-
// Capture the client inside the handler
402-
capturedClient = SentryCore.getClient() as CloudflareClient;
403-
// Add Content-Length to skip streaming detection probing
404-
const response = new Response('test');
405-
response.headers.set('content-length', '4');
406-
return response;
407-
},
408-
);
409-
410-
// Verify the client was created and has hooks before disposal
411-
expect(capturedClient).toBeInstanceOf(CloudflareClient);
412-
const hooksBeforeDisposal = (capturedClient as unknown as { _hooks: Record<string, Set<unknown>> })._hooks;
413-
expect(Object.keys(hooksBeforeDisposal).length).toBeGreaterThan(0);
414-
415-
// Wait for all waitUntil promises (flush + dispose happens here)
416-
// The flushAndDispose promise is passed to waitUntil
417-
expect(waitUntilPromises.length).toBeGreaterThan(0);
418-
await Promise.all(waitUntilPromises);
419-
420-
// After disposal, the internal state should be cleared
421-
// We can verify this by checking that the hooks are cleared
422-
const hooks = (capturedClient as unknown as { _hooks: Record<string, Set<unknown>> })._hooks;
423-
const eventProcessors = (capturedClient as unknown as { _eventProcessors: unknown[] })._eventProcessors;
424-
const integrations = (capturedClient as unknown as { _integrations: Record<string, unknown> })._integrations;
425-
426-
expect(Object.keys(hooks)).toHaveLength(0);
427-
expect(eventProcessors).toHaveLength(0);
428-
expect(Object.keys(integrations)).toHaveLength(0);
429-
});
430-
431-
test('dispose clears span lifecycle listeners', async () => {
432-
const client = new CloudflareClient({
433-
dsn: MOCK_OPTIONS.dsn,
434-
transport: () => ({ send: async () => ({}), flush: async () => true }),
435-
integrations: [],
436-
stackParser: () => [],
437-
});
438-
439-
// Get the internal hooks before dispose
440-
const hooksBeforeDispose = (client as unknown as { _hooks: Record<string, Set<unknown>> })._hooks;
441-
const spanStartHooks = hooksBeforeDispose['spanStart'];
442-
const spanEndHooks = hooksBeforeDispose['spanEnd'];
443-
444-
// Verify hooks exist before dispose
445-
expect(spanStartHooks?.size).toBeGreaterThan(0);
446-
expect(spanEndHooks?.size).toBeGreaterThan(0);
447-
448-
// Dispose the client
449-
client.dispose();
450-
451-
// Verify hooks are cleared after dispose
452-
const hooksAfterDispose = (client as unknown as { _hooks: Record<string, Set<unknown>> })._hooks;
453-
expect(Object.keys(hooksAfterDispose)).toHaveLength(0);
454-
});
455-
456-
test('dispose clears pending spans', async () => {
457-
const client = new CloudflareClient({
458-
dsn: MOCK_OPTIONS.dsn,
459-
transport: () => ({ send: async () => ({}), flush: async () => true }),
460-
integrations: [],
461-
stackParser: () => [],
462-
});
463-
464-
// Add some pending spans
465-
const pendingSpans = (client as unknown as { _pendingSpans: Set<string> })._pendingSpans;
466-
pendingSpans.add('span1');
467-
pendingSpans.add('span2');
468-
expect(pendingSpans.size).toBe(2);
469-
470-
// Dispose the client
471-
client.dispose();
472-
473-
// Verify pending spans are cleared
474-
expect(pendingSpans.size).toBe(0);
475-
});
476-
});
477372
});
478373

479374
function createMockExecutionContext(): ExecutionContext {

packages/cloudflare/test/testUtils.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { context, propagation, trace } from '@opentelemetry/api';
22
import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';
3-
import { _INTERNAL_resetSdkCache } from '../src/sdk';
43

54
function resetGlobals(): void {
65
getCurrentScope().clear();
@@ -19,5 +18,4 @@ function cleanupOtel(): void {
1918
export function resetSdk(): void {
2019
resetGlobals();
2120
cleanupOtel();
22-
_INTERNAL_resetSdkCache();
2321
}

packages/core/src/client.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,40 +1118,6 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
11181118
}
11191119
}
11201120

1121-
/**
1122-
* Disposes of the client and releases all resources.
1123-
*
1124-
* This method clears all hooks, event processors, and integration references
1125-
* to allow the client to be garbage collected. Call this method when you're
1126-
* done using the client and want to ensure all retained references are released.
1127-
*
1128-
* After calling dispose(), the client should not be used anymore.
1129-
*/
1130-
public dispose(): void {
1131-
// Clear all hook callbacks to release closures and their captured variables
1132-
for (const hookName of Object.keys(this._hooks)) {
1133-
this._hooks[hookName]?.clear();
1134-
}
1135-
this._hooks = {};
1136-
1137-
// Clear event processors which may hold references to integrations and client
1138-
this._eventProcessors = [];
1139-
1140-
// Clear integration references
1141-
this._integrations = {};
1142-
1143-
// Clear outcomes tracking
1144-
this._outcomes = {};
1145-
1146-
// Clear transport reference to break the circular reference via recordDroppedEvent.bind(this)
1147-
// The transport holds a bound function that retains the client, so we need to clear it
1148-
// Use type assertion via unknown to bypass readonly and protected modifiers
1149-
(this as unknown as { _transport?: Transport })._transport = undefined;
1150-
1151-
// Clear the promise buffer to release any pending promises
1152-
(this as unknown as { _promiseBuffer?: unknown })._promiseBuffer = undefined;
1153-
}
1154-
11551121
/**
11561122
* Send an envelope to Sentry.
11571123
*/

packages/core/src/instrument/handlers.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,10 @@ export type InstrumentHandlerCallback = (data: any) => void;
1818
const handlers: { [key in InstrumentHandlerType]?: InstrumentHandlerCallback[] } = {};
1919
const instrumented: { [key in InstrumentHandlerType]?: boolean } = {};
2020

21-
/**
22-
* Add a handler function.
23-
* Returns a function to remove the handler.
24-
*/
25-
export function addHandler(type: InstrumentHandlerType, handler: InstrumentHandlerCallback): () => void {
21+
/** Add a handler function. */
22+
export function addHandler(type: InstrumentHandlerType, handler: InstrumentHandlerCallback): void {
2623
handlers[type] = handlers[type] || [];
2724
handlers[type].push(handler);
28-
29-
// Return unsubscribe function
30-
return () => {
31-
const typeHandlers = handlers[type];
32-
if (typeHandlers) {
33-
const index = typeHandlers.indexOf(handler);
34-
if (index !== -1) {
35-
typeHandlers.splice(index, 1);
36-
}
37-
}
38-
};
3925
}
4026

4127
/**

0 commit comments

Comments
 (0)