Skip to content

Commit

Permalink
Merge branch '8.x.x' into feat/scope-binding-mode
Browse files Browse the repository at this point in the history
  • Loading branch information
adinauer authored Dec 20, 2024
2 parents 23ebcf5 + 78415f3 commit 524e096
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
- Previously only the body was cached which could lead to problems in the FilterChain as Request parameters were not available
- We now hold a strong reference to the underlying OpenTelemetry span when it is created through Sentry API ([#3997](https://github.com/getsentry/sentry-java/pull/3997))
- This keeps it from being garbage collected too early
- Close backpressure monitor on SDK shutdown ([#3998](https://github.com/getsentry/sentry-java/pull/3998))
- Due to the backpressure monitor rescheduling a task to run every 10s, it very likely caused shutdown to wait the full `shutdownTimeoutMillis` (defaulting to 2s) instead of being able to terminate immediately

## 8.0.0-rc.2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import io.sentry.InitPriority;
import io.sentry.Sentry;
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SentryOptions;
import io.sentry.protocol.SdkVersion;
import io.sentry.protocol.SentryPackage;
Expand Down Expand Up @@ -39,7 +38,6 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
options -> {
options.setEnableExternalConfiguration(true);
options.setInitPriority(InitPriority.HIGH);
options.setOpenTelemetryMode(SentryOpenTelemetryMode.AGENT);
final @Nullable SdkVersion sdkVersion = createSdkVersion(options, versionInfoHolder);
if (sdkVersion != null) {
options.setSdkVersion(sdkVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public final class OtelStrongRefSpanWrapper implements IOtelSpanWrapper {

private final @NotNull IOtelSpanWrapper delegate;

public OtelStrongRefSpanWrapper(@NotNull Span otelSpan, IOtelSpanWrapper delegate) {
public OtelStrongRefSpanWrapper(@NotNull Span otelSpan, @NotNull IOtelSpanWrapper delegate) {
this.otelSpan = otelSpan;
this.delegate = delegate;
}
Expand Down
3 changes: 3 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -3800,17 +3800,20 @@ public final class io/sentry/UserFeedback$JsonKeys {

public final class io/sentry/backpressure/BackpressureMonitor : io/sentry/backpressure/IBackpressureMonitor, java/lang/Runnable {
public fun <init> (Lio/sentry/SentryOptions;Lio/sentry/IScopes;)V
public fun close ()V
public fun getDownsampleFactor ()I
public fun run ()V
public fun start ()V
}

public abstract interface class io/sentry/backpressure/IBackpressureMonitor {
public abstract fun close ()V
public abstract fun getDownsampleFactor ()I
public abstract fun start ()V
}

public final class io/sentry/backpressure/NoOpBackpressureMonitor : io/sentry/backpressure/IBackpressureMonitor {
public fun close ()V
public fun getDownsampleFactor ()I
public static fun getInstance ()Lio/sentry/backpressure/NoOpBackpressureMonitor;
public fun start ()V
Expand Down
1 change: 1 addition & 0 deletions sentry/src/main/java/io/sentry/Scopes.java
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ public void close(final boolean isRestarting) {

configureScope(scope -> scope.clear());
configureScope(ScopeType.ISOLATION, scope -> scope.clear());
getOptions().getBackpressureMonitor().close();
getOptions().getTransactionProfiler().close();
getOptions().getTransactionPerformanceCollector().close();
final @NotNull ISentryExecutorService executorService = getOptions().getExecutorService();
Expand Down
9 changes: 7 additions & 2 deletions sentry/src/main/java/io/sentry/Sentry.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.sentry;

import io.sentry.backpressure.BackpressureMonitor;
import io.sentry.backpressure.NoOpBackpressureMonitor;
import io.sentry.cache.EnvelopeCache;
import io.sentry.cache.IEnvelopeCache;
import io.sentry.config.PropertiesProviderFactory;
Expand Down Expand Up @@ -369,7 +370,6 @@ private static void initForOpenTelemetryMaybe(SentryOptions options) {
OpenTelemetryUtil.applyIgnoredSpanOrigins(options, new LoadClass());
}

@SuppressWarnings("UnusedMethod")
private static void initScopesStorage(SentryOptions options) {
getScopesStorage().close();
if (SentryOpenTelemetryMode.OFF == options.getOpenTelemetryMode()) {
Expand Down Expand Up @@ -513,6 +513,8 @@ private static void initConfigurations(final @NotNull SentryOptions options) {
}
logger.log(SentryLevel.INFO, "Initializing SDK with DSN: '%s'", options.getDsn());

OpenTelemetryUtil.applyIgnoredSpanOrigins(options, new LoadClass());

// TODO: read values from conf file, Build conf or system envs
// eg release, distinctId, sentryClientName

Expand Down Expand Up @@ -598,7 +600,10 @@ private static void initConfigurations(final @NotNull SentryOptions options) {
}

if (options.isEnableBackpressureHandling() && Platform.isJvm()) {
options.setBackpressureMonitor(new BackpressureMonitor(options, ScopesAdapter.getInstance()));
if (options.getBackpressureMonitor() instanceof NoOpBackpressureMonitor) {
options.setBackpressureMonitor(
new BackpressureMonitor(options, ScopesAdapter.getInstance()));
}
options.getBackpressureMonitor().start();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import io.sentry.IScopes;
import io.sentry.ISentryExecutorService;
import io.sentry.ISentryLifecycleToken;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.util.AutoClosableReentrantLock;
import java.util.concurrent.Future;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public final class BackpressureMonitor implements IBackpressureMonitor, Runnable {
static final int MAX_DOWNSAMPLE_FACTOR = 10;
Expand All @@ -14,6 +18,8 @@ public final class BackpressureMonitor implements IBackpressureMonitor, Runnable
private final @NotNull SentryOptions sentryOptions;
private final @NotNull IScopes scopes;
private int downsampleFactor = 0;
private volatile @Nullable Future<?> latestScheduledRun = null;
private final @NotNull AutoClosableReentrantLock lock = new AutoClosableReentrantLock();

public BackpressureMonitor(
final @NotNull SentryOptions sentryOptions, final @NotNull IScopes scopes) {
Expand All @@ -37,6 +43,16 @@ public int getDownsampleFactor() {
return downsampleFactor;
}

@Override
public void close() {
final @Nullable Future<?> currentRun = latestScheduledRun;
if (currentRun != null) {
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
currentRun.cancel(true);
}
}
}

void checkHealth() {
if (isHealthy()) {
if (downsampleFactor > 0) {
Expand All @@ -62,7 +78,9 @@ void checkHealth() {
private void reschedule(final int delay) {
final @NotNull ISentryExecutorService executorService = sentryOptions.getExecutorService();
if (!executorService.isClosed()) {
executorService.schedule(this, delay);
try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) {
latestScheduledRun = executorService.schedule(this, delay);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public interface IBackpressureMonitor {
void start();

int getDownsampleFactor();

void close();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ public void start() {
public int getDownsampleFactor() {
return 0;
}

@Override
public void close() {
// do nothing
}
}
3 changes: 3 additions & 0 deletions sentry/src/test/java/io/sentry/ScopesTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1760,15 +1760,18 @@ class ScopesTest {
val executor = mock<ISentryExecutorService>()
val profiler = mock<ITransactionProfiler>()
val performanceCollector = mock<TransactionPerformanceCollector>()
val backpressureMonitorMock = mock<IBackpressureMonitor>()
val options = SentryOptions().apply {
dsn = "https://key@sentry.io/proj"
cacheDirPath = file.absolutePath
executorService = executor
setTransactionProfiler(profiler)
transactionPerformanceCollector = performanceCollector
backpressureMonitor = backpressureMonitorMock
}
val sut = createScopes(options)
sut.close()
verify(backpressureMonitorMock).close()
verify(executor).close(any())
verify(profiler).close()
verify(performanceCollector).close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import io.sentry.IScopes
import io.sentry.ISentryExecutorService
import io.sentry.SentryOptions
import io.sentry.backpressure.BackpressureMonitor.MAX_DOWNSAMPLE_FACTOR
import org.mockito.ArgumentMatchers.eq
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import java.util.concurrent.Future
Expand All @@ -19,10 +21,12 @@ class BackpressureMonitorTest {
val options = SentryOptions()
val scopes = mock<IScopes>()
val executor = mock<ISentryExecutorService>()
val returnedFuture = mock<Future<Any>>()
fun getSut(): BackpressureMonitor {
options.executorService = executor
whenever(executor.isClosed).thenReturn(false)
whenever(executor.schedule(any(), any())).thenReturn(mock<Future<Any>>())
whenever(executor.schedule(any(), any())).thenReturn(returnedFuture)
whenever(returnedFuture.cancel(any())).thenReturn(true)
return BackpressureMonitor(options, scopes)
}
}
Expand Down Expand Up @@ -80,4 +84,17 @@ class BackpressureMonitorTest {

verify(fixture.executor).schedule(any(), any())
}

@Test
fun `close cancels latest job`() {
val sut = fixture.getSut()
sut.run()

verify(fixture.executor).schedule(any(), any())
verify(fixture.returnedFuture, never()).cancel(any())

sut.close()

verify(fixture.returnedFuture).cancel(eq(true))
}
}

0 comments on commit 524e096

Please sign in to comment.