-
-
Couldn't load subscription status.
- Fork 460
Hubs/Scopes Merge 15 - Replace ThreadLocal with scope storage
#3317
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
Changes from all commits
305baf5
95f5e1b
27f2398
ce3c14f
ce615f4
22ddc00
305c217
da927bc
8279276
9bfc086
b998e50
739827a
69f2d63
792d482
9bcbce6
3f25a4b
d6fb40a
7752bcc
07545e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package io.sentry; | ||
|
|
||
| import org.jetbrains.annotations.NotNull; | ||
| import org.jetbrains.annotations.Nullable; | ||
|
|
||
| public final class DefaultScopesStorage implements IScopesStorage { | ||
|
|
||
| private static final @NotNull ThreadLocal<IScopes> currentScopes = new ThreadLocal<>(); | ||
|
|
||
| @Override | ||
| public ISentryLifecycleToken set(@Nullable IScopes scopes) { | ||
| final @Nullable IScopes oldScopes = get(); | ||
| currentScopes.set(scopes); | ||
| return new DefaultScopesLifecycleToken(oldScopes); | ||
| } | ||
|
|
||
| @Override | ||
| public @Nullable IScopes get() { | ||
| return currentScopes.get(); | ||
| } | ||
|
|
||
| @Override | ||
| public void close() { | ||
| // TODO prevent further storing? would this cause problems if singleton, closed and | ||
| // re-initialized? | ||
| currentScopes.remove(); | ||
| } | ||
|
|
||
| static final class DefaultScopesLifecycleToken implements ISentryLifecycleToken { | ||
|
|
||
| private final @Nullable IScopes oldValue; | ||
|
|
||
| DefaultScopesLifecycleToken(final @Nullable IScopes scopes) { | ||
| this.oldValue = scopes; | ||
| } | ||
|
|
||
| @Override | ||
| public void close() { | ||
| currentScopes.set(oldValue); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package io.sentry; | ||
|
|
||
| import org.jetbrains.annotations.Nullable; | ||
|
|
||
| public interface IScopesStorage { | ||
|
|
||
| ISentryLifecycleToken set(final @Nullable IScopes scopes); | ||
|
|
||
| @Nullable | ||
| IScopes get(); | ||
|
|
||
| void close(); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package io.sentry; | ||
|
|
||
| public interface ISentryLifecycleToken extends AutoCloseable { | ||
|
|
||
| // overridden to not have a checked exception on the method. | ||
| @Override | ||
| void close(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package io.sentry; | ||
|
|
||
| import org.jetbrains.annotations.Nullable; | ||
|
|
||
| public final class NoOpScopesStorage implements IScopesStorage { | ||
| private static final NoOpScopesStorage instance = new NoOpScopesStorage(); | ||
|
|
||
| private NoOpScopesStorage() {} | ||
|
|
||
| public static NoOpScopesStorage getInstance() { | ||
| return instance; | ||
| } | ||
|
|
||
| @Override | ||
| public ISentryLifecycleToken set(@Nullable IScopes scopes) { | ||
| return NoOpScopesLifecycleToken.getInstance(); | ||
| } | ||
|
|
||
| @Override | ||
| public @Nullable IScopes get() { | ||
| return NoOpScopes.getInstance(); | ||
| } | ||
|
|
||
| @Override | ||
| public void close() {} | ||
|
|
||
| static final class NoOpScopesLifecycleToken implements ISentryLifecycleToken { | ||
|
|
||
| private static final NoOpScopesLifecycleToken instance = new NoOpScopesLifecycleToken(); | ||
|
|
||
| private NoOpScopesLifecycleToken() {} | ||
|
|
||
| public static NoOpScopesLifecycleToken getInstance() { | ||
| return instance; | ||
| } | ||
|
|
||
| @Override | ||
| public void close() {} | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,8 +43,7 @@ public final class Sentry { | |
|
|
||
| private Sentry() {} | ||
|
|
||
| /** Holds Hubs per thread or only mainScopes if globalHubMode is enabled. */ | ||
| private static final @NotNull ThreadLocal<IScopes> currentScopes = new ThreadLocal<>(); | ||
| private static volatile @NotNull IScopesStorage scopesStorage = new DefaultScopesStorage(); | ||
|
|
||
| /** The Main Hub or NoOp if Sentry is disabled. */ | ||
| private static volatile @NotNull IScopes mainScopes = NoOpScopes.getInstance(); | ||
|
|
@@ -83,13 +82,17 @@ private Sentry() {} | |
| if (globalHubMode) { | ||
| return mainScopes; | ||
| } | ||
| IScopes hub = currentScopes.get(); | ||
| if (hub == null || hub.isNoOp()) { | ||
| IScopes scopes = getScopesStorage().get(); | ||
| if (scopes == null || scopes.isNoOp()) { | ||
| // TODO fork instead | ||
| hub = mainScopes.clone(); | ||
| currentScopes.set(hub); | ||
| scopes = mainScopes.clone(); | ||
| getScopesStorage().set(scopes); | ||
| } | ||
| return hub; | ||
| return scopes; | ||
| } | ||
|
|
||
| private static @NotNull IScopesStorage getScopesStorage() { | ||
| return scopesStorage; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -110,14 +113,15 @@ private Sentry() {} | |
|
|
||
| @ApiStatus.Internal // exposed for the coroutines integration in SentryContext | ||
| @Deprecated | ||
| @SuppressWarnings("deprecation") | ||
| @SuppressWarnings({"deprecation", "InlineMeSuggester"}) | ||
| public static void setCurrentHub(final @NotNull IHub hub) { | ||
| currentScopes.set(hub); | ||
| setCurrentScopes(hub); | ||
| } | ||
|
|
||
| @ApiStatus.Internal // exposed for the coroutines integration in SentryContext | ||
| public static void setCurrentScopes(final @NotNull IScopes scopes) { | ||
| currentScopes.set(scopes); | ||
| public static @NotNull ISentryLifecycleToken setCurrentScopes(final @NotNull IScopes scopes) { | ||
| return getScopesStorage().set(scopes); | ||
| } | ||
adinauer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -253,14 +257,18 @@ private static synchronized void init( | |
| options.getLogger().log(SentryLevel.INFO, "GlobalHubMode: '%s'", String.valueOf(globalHubMode)); | ||
| Sentry.globalHubMode = globalHubMode; | ||
|
|
||
| final IScopes hub = getCurrentScopes(); | ||
| final IScopes scopes = getCurrentScopes(); | ||
| final IScope rootScope = new Scope(options); | ||
| final IScope rootIsolationScope = new Scope(options); | ||
| mainScopes = new Scopes(rootScope, rootIsolationScope, options, "Sentry.init"); | ||
| // TODO should use separate isolation scope: | ||
| // final IScope rootIsolationScope = new Scope(options); | ||
| // TODO should be: | ||
| // getGlobalScope().bindClient(new SentryClient(options)); | ||
| rootScope.bindClient(new SentryClient(options)); | ||
| mainScopes = new Scopes(rootScope, rootScope, options, "Sentry.init"); | ||
|
|
||
| currentScopes.set(mainScopes); | ||
| getScopesStorage().set(mainScopes); | ||
|
|
||
| hub.close(true); | ||
| scopes.close(true); | ||
|
|
||
| // If the executorService passed in the init is the same that was previously closed, we have to | ||
| // set a new one | ||
|
|
@@ -508,7 +516,7 @@ public static synchronized void close() { | |
| final IScopes scopes = getCurrentScopes(); | ||
| mainScopes = NoOpScopes.getInstance(); | ||
| // remove thread local to avoid memory leak | ||
| currentScopes.remove(); | ||
| getScopesStorage().close(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If not in If one would Not sure about the implications, just wanted to point out a potential issue. Please correct me if I'm wrong :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, maybe we can give https://github.com/getsentry/sentry-java/pull/2711/files a try once we're done with most changes for the major. |
||
| scopes.close(false); | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.