Skip to content

feat(core): Remove getCurrentHub from AsyncContextStrategy #11581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions packages/core/src/asyncContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Hub, Integration } from '@sentry/types';
import type { Integration } from '@sentry/types';
import type { Scope } from '@sentry/types';
import { GLOBAL_OBJ } from '@sentry/utils';
import type { startInactiveSpan, startSpan, startSpanManual, suppressTracing, withActiveSpan } from './tracing/trace';
Expand All @@ -10,12 +10,6 @@ import type { getActiveSpan } from './utils/spanUtils';
* Strategy used to track async context.
*/
export interface AsyncContextStrategy {
/**
* Gets the currently active hub.
*/
// eslint-disable-next-line deprecation/deprecation
getCurrentHub: () => Hub;

/**
* Fork the isolation scope inside of the provided callback.
*/
Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/getCurrentHubShim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ export function getCurrentHubShim(): Hub {
};
}

/**
* Returns the default hub instance.
*
* If a hub is already registered in the global carrier but this module
* contains a more recent version, it replaces the registered version.
* Otherwise, the currently registered hub will be returned.
*
* @deprecated Use the respective replacement method directly instead.
*/
// eslint-disable-next-line deprecation/deprecation
export const getCurrentHub = getCurrentHubShim;

/**
* Sends the current Session on the scope
*/
Expand Down
19 changes: 0 additions & 19 deletions packages/core/src/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,24 +496,6 @@ export class Hub implements HubInterface {
}
}

/**
* Returns the default hub instance.
*
* If a hub is already registered in the global carrier but this module
* contains a more recent version, it replaces the registered version.
* Otherwise, the currently registered hub will be returned.
*
* @deprecated Use the respective replacement method directly instead.
*/
// eslint-disable-next-line deprecation/deprecation
export function getCurrentHub(): HubInterface {
// Get main carrier (global for every environment)
const carrier = getMainCarrier();

const acs = getAsyncContextStrategy(carrier);
return acs.getCurrentHub() || getGlobalHub();
}
Comment on lines -509 to -515
Copy link
Member Author

Choose a reason for hiding this comment

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

It's no longer necessary to read from the carrier here since acs doesn't have the getCurrentHub method anymore. This means that we can replace this entire implementation with the shim which in turn will again forward its respective calls to the globalHub (to be renamed).

Copy link
Member

Choose a reason for hiding this comment

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

I think we need to remove getGlobalHub usage and make everything rely on the shim, though that does mean we need to refactor more of the return values in getHubStackAsyncContextStrategy

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, I talked about this with @mydea and that's basically what we should do. getHubStackAsyncContextStrategy has to stay in one way or the other since our fallback (i.e. browser) async context strategy is still a stack-based scope hierarchy. getGlobalHub currently returns a Hub class instance which we can probably cut down a lot to only handle the scope stack. At this point we can then also rename this to something like globalScopeStackAsyncContextStrategy.


/** Get the default current scope. */
export function getDefaultCurrentScope(): Scope {
return getGlobalSingleton('defaultCurrentScope', () => new Scope());
Expand Down Expand Up @@ -586,7 +568,6 @@ function withIsolationScope<T>(callback: (isolationScope: ScopeInterface) => T):
/* eslint-disable deprecation/deprecation */
function getHubStackAsyncContextStrategy(): AsyncContextStrategy {
return {
getCurrentHub: getGlobalHub,
withIsolationScope,
withScope,
withSetScope,
Expand Down
4 changes: 1 addition & 3 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ export {
addEventProcessor,
} from './exports';
export {
// eslint-disable-next-line deprecation/deprecation
getCurrentHub,
getDefaultCurrentScope,
getDefaultIsolationScope,
} from './hub';
Expand Down Expand Up @@ -107,4 +105,4 @@ export { addTracingHeadersToFetchRequest, instrumentFetchRequest } from './fetch
export { trpcMiddleware } from './trpc';

// eslint-disable-next-line deprecation/deprecation
export { getCurrentHubShim } from './getCurrentHubShim';
export { getCurrentHubShim, getCurrentHub } from './getCurrentHubShim';
29 changes: 16 additions & 13 deletions packages/core/src/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Client, ClientOptions, Hub as HubInterface } from '@sentry/types';
import type { Client, ClientOptions } from '@sentry/types';
import { consoleSandbox, logger } from '@sentry/utils';
import { getCurrentScope } from './currentScopes';

import { getMainCarrier, getSentryCarrier } from './asyncContext';
import { DEBUG_BUILD } from './debug-build';
import type { Hub } from './hub';
import { getCurrentHub } from './hub';

/** A class object that can instantiate Client objects. */
export type ClientClass<F extends Client, O extends ClientOptions> = new (options: O) => F;
Expand Down Expand Up @@ -44,19 +44,22 @@ export function initAndBind<F extends Client, O extends ClientOptions>(
*/
export function setCurrentClient(client: Client): void {
getCurrentScope().setClient(client);
registerClientOnGlobalHub(client);
}

// is there a hub too?
/**
* Unfortunately, we still have to manually bind the client to the "hub" set on the global
* Sentry carrier object. This is because certain scripts (e.g. our loader script) obtain
* the client via `window.__SENTRY__.hub.getClient()`.
*
* @see {@link hub.ts getGlobalHub}
*/
function registerClientOnGlobalHub(client: Client): void {
// eslint-disable-next-line deprecation/deprecation
const hub = getCurrentHub();
if (isHubClass(hub)) {
const sentryGlobal = getSentryCarrier(getMainCarrier()) as { hub?: Hub };
// eslint-disable-next-line deprecation/deprecation
if (sentryGlobal.hub && typeof sentryGlobal.hub.getStackTop === 'function') {
// eslint-disable-next-line deprecation/deprecation
const top = hub.getStackTop();
top.client = client;
sentryGlobal.hub.getStackTop().client = client;
}
}

// eslint-disable-next-line deprecation/deprecation
function isHubClass(hub: HubInterface): hub is Hub {
// eslint-disable-next-line deprecation/deprecation
return !!(hub as Hub).getStackTop;
}
11 changes: 4 additions & 7 deletions packages/core/src/trpc.ts
Copy link
Member Author

Choose a reason for hiding this comment

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

The imports in this file caused a (rather unrelated but still existing) circular dependency in the core package.

Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { isThenable, normalize } from '@sentry/utils';
import {
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
captureException,
setContext,
startSpanManual,
} from '.';

import { getClient } from './currentScopes';
import { captureException, setContext } from './exports';
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes';
import { startSpanManual } from './tracing';

interface SentryTrpcMiddlewareOptions {
/** Whether to include procedure inputs in reported events. Defaults to `false`. */
Expand Down
27 changes: 2 additions & 25 deletions packages/opentelemetry/src/asyncContextStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import * as api from '@opentelemetry/api';
import {
getCurrentHubShim,
getDefaultCurrentScope,
getDefaultIsolationScope,
setAsyncContextStrategy,
} from '@sentry/core';
import { getDefaultCurrentScope, getDefaultIsolationScope, setAsyncContextStrategy } from '@sentry/core';
import type { withActiveSpan as defaultWithActiveSpan } from '@sentry/core';
import type { Hub, Scope } from '@sentry/types';
import type { Scope } from '@sentry/types';

import {
SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY,
Expand Down Expand Up @@ -40,23 +35,6 @@ export function setOpenTelemetryContextAsyncContextStrategy(): void {
};
}

// eslint-disable-next-line deprecation/deprecation
function getCurrentHub(): Hub {
// eslint-disable-next-line deprecation/deprecation
const hub = getCurrentHubShim();
return {
...hub,
getScope: () => {
const scopes = getScopes();
return scopes.scope;
},
getIsolationScope: () => {
const scopes = getScopes();
return scopes.isolationScope;
},
};
}

function withScope<T>(callback: (scope: Scope) => T): T {
const ctx = api.context.active();

Expand Down Expand Up @@ -114,7 +92,6 @@ export function setOpenTelemetryContextAsyncContextStrategy(): void {
}

setAsyncContextStrategy({
getCurrentHub,
withScope,
withSetScope,
withSetIsolationScope,
Expand Down
27 changes: 2 additions & 25 deletions packages/vercel-edge/src/async.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import {
getCurrentHubShim,
getDefaultCurrentScope,
getDefaultIsolationScope,
setAsyncContextStrategy,
} from '@sentry/core';
import type { Hub, Scope } from '@sentry/types';
import { getDefaultCurrentScope, getDefaultIsolationScope, setAsyncContextStrategy } from '@sentry/core';
import type { Scope } from '@sentry/types';
import { GLOBAL_OBJ, logger } from '@sentry/utils';

import { DEBUG_BUILD } from './debug-build';
Expand Down Expand Up @@ -51,23 +46,6 @@ export function setAsyncLocalStorageAsyncContextStrategy(): void {
};
}

// eslint-disable-next-line deprecation/deprecation
function getCurrentHub(): Hub {
// eslint-disable-next-line deprecation/deprecation
const hub = getCurrentHubShim();
return {
...hub,
getScope: () => {
const scopes = getScopes();
return scopes.scope;
},
getIsolationScope: () => {
const scopes = getScopes();
return scopes.isolationScope;
},
};
}

function withScope<T>(callback: (scope: Scope) => T): T {
const scope = getScopes().scope.clone();
const isolationScope = getScopes().isolationScope;
Expand Down Expand Up @@ -99,7 +77,6 @@ export function setAsyncLocalStorageAsyncContextStrategy(): void {
}

setAsyncContextStrategy({
getCurrentHub,
withScope,
withSetScope,
withIsolationScope,
Expand Down