Skip to content
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Behavioral Changes

- Measure HTTP rate-limit backoff on a monotonic clock instead of the wall clock, so that a device time change no longer lifts or extends an active rate limit ([#6030](https://github.com/getsentry/sentry-java/pull/6030))

### Fixes

- Update `SentryTraced` so that it now honors `options.setIgnoredSpanOrigins` ([#6058](https://github.com/getsentry/sentry-java/pull/6058))
Expand All @@ -19,6 +23,7 @@

- Add an internal `MonotonicTicker` abstraction with `Deadline` and `Stopwatch` primitives ([#6028](https://github.com/getsentry/sentry-java/pull/6028))
- Add internal `Timestamp`, `EpochClock` and `AnchoredClock`, so related instants project from one wall-clock reading instead of each reading the clock ([#6045](https://github.com/getsentry/sentry-java/pull/6045))
- Deprecate `RateLimiter(ICurrentDateProvider, SentryOptions)` in favor of `RateLimiter(SentryOptions)`, whose backoff is measured on a monotonic ticker ([#6030](https://github.com/getsentry/sentry-java/pull/6030))

### Dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public ApacheHttpClientTransportFactory(final @NotNull TimeValue connectionTimeT
.setResponseTimeout(options.getReadTimeoutMillis(), TimeUnit.MILLISECONDS)
.build())
.build();
final RateLimiter rateLimiter = new RateLimiter(options);
final RateLimiter rateLimiter = RateLimiter.create(options.getMonotonicTicker(), options);

return new ApacheHttpClientTransport(options, requestDetails, httpclient, rateLimiter);
}
Expand Down
9 changes: 8 additions & 1 deletion sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -3654,7 +3654,7 @@ public final class io/sentry/SentryOpenTelemetryMode : java/lang/Enum {
public static fun values ()[Lio/sentry/SentryOpenTelemetryMode;
}

public class io/sentry/SentryOptions {
public class io/sentry/SentryOptions : io/sentry/transport/RateLimiterConfig {
public static final field DEFAULT_PROPAGATION_TARGETS Ljava/lang/String;
public static final field MAX_EVENT_SIZE_BYTES J
protected final field lock Lio/sentry/util/AutoClosableReentrantLock;
Expand Down Expand Up @@ -7706,6 +7706,7 @@ public final class io/sentry/transport/RateLimiter : java/io/Closeable {
public fun <init> (Lio/sentry/transport/ICurrentDateProvider;Lio/sentry/SentryOptions;)V
public fun addRateLimitObserver (Lio/sentry/transport/RateLimiter$IRateLimitObserver;)V
public fun close ()V
public static fun create (Lio/sentry/time/MonotonicTicker;Lio/sentry/transport/RateLimiterConfig;)Lio/sentry/transport/RateLimiter;
public fun filter (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/SentryEnvelope;
public fun isActiveForCategory (Lio/sentry/DataCategory;)Z
public fun isAnyRateLimitActive ()Z
Expand All @@ -7717,6 +7718,12 @@ public abstract interface class io/sentry/transport/RateLimiter$IRateLimitObserv
public abstract fun onRateLimitChanged (Lio/sentry/transport/RateLimiter;)V
}

public abstract interface class io/sentry/transport/RateLimiterConfig {
public abstract fun getClientReportRecorder ()Lio/sentry/clientreport/IClientReportRecorder;
public abstract fun getLogger ()Lio/sentry/ILogger;
public abstract fun getTimerExecutorService ()Lio/sentry/ISentryExecutorService;
}

public final class io/sentry/transport/ReusableCountLatch {
public fun <init> ()V
public fun <init> (I)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public final class AsyncHttpTransportFactory implements ITransportFactory {
Objects.requireNonNull(requestDetails, "requestDetails is required");

return new AsyncHttpTransport(
options, new RateLimiter(options), options.getTransportGate(), requestDetails);
options,
RateLimiter.create(options.getMonotonicTicker(), options),
options.getTransportGate(),
requestDetails);
}
}
6 changes: 5 additions & 1 deletion sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.sentry.transport.ITransportGate;
import io.sentry.transport.NoOpEnvelopeCache;
import io.sentry.transport.NoOpTransportGate;
import io.sentry.transport.RateLimiterConfig;
import io.sentry.util.AutoClosableReentrantLock;
import io.sentry.util.LazyEvaluator;
import io.sentry.util.LoadClass;
Expand Down Expand Up @@ -58,7 +59,7 @@

/** Sentry SDK options */
@Open
public class SentryOptions {
public class SentryOptions implements RateLimiterConfig {
Comment thread
runningcode marked this conversation as resolved.

@ApiStatus.Internal public static final @NotNull String DEFAULT_PROPAGATION_TARGETS = ".*";

Expand Down Expand Up @@ -847,6 +848,7 @@ public void setDebug(final boolean debug) {
*
* @return the logger
*/
@Override
public @NotNull ILogger getLogger() {
return logger;
}
Expand Down Expand Up @@ -1610,6 +1612,7 @@ public void setExecutorService(final @NotNull ISentryExecutorService executorSer
* @return the timer executor service
*/
@ApiStatus.Internal
@Override
@NotNull
public ISentryExecutorService getTimerExecutorService() {
return timerExecutorService;
Expand Down Expand Up @@ -2601,6 +2604,7 @@ public void setInstrumenter(final @NotNull Instrumenter instrumenter) {
* @return a client report recorder or NoOp
*/
@ApiStatus.Internal
@Override
public @NotNull IClientReportRecorder getClientReportRecorder() {
return clientReportRecorder;
}
Expand Down
11 changes: 7 additions & 4 deletions sentry/src/main/java/io/sentry/time/Deadline.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@ private Deadline(final @NotNull MonotonicTicker ticker, final long deadlineNanos
}

/**
* A deadline {@code amount} of {@code unit} from now.
* A deadline {@code amount} of {@code unit} from now, or one that has already {@link #passed} if
* {@code amount} is negative.
*
* @throws IllegalArgumentException if {@code amount} is negative. A deadline that starts out in
* the past is a sign error at the call site; {@link #passed} says it deliberately.
* <p>Negative amounts are tolerated because callers pass durations parsed from server headers,
Comment thread
runningcode marked this conversation as resolved.
* where a bogus value must degrade to "no wait" rather than throw out of response handling.
* Clamping rather than adding a negative offset also keeps the tick arithmetic away from
* wrapping.
*/
public static @NotNull Deadline after(
final @NotNull MonotonicTicker ticker, final long amount, final @NotNull TimeUnit unit) {
if (amount < 0) {
throw new IllegalArgumentException("Deadline amount must not be negative, but was " + amount);
return passed(ticker);
Comment thread
runningcode marked this conversation as resolved.
}
return new Deadline(ticker, ticker.tickNanos() + unit.toNanos(amount));
}
Expand Down
Loading
Loading