Skip to content

Commit 34b5305

Browse files
authored
Synchronize Baggage keyValues (#4327)
* Synchronize Baggage keyValues * Update Changelog * Add todo for SpanContext copy ctor * Synchronize iterators * Use AutoClosableReentrantLock in favor of synchronized * Ensure null values work
1 parent 9201bd3 commit 34b5305

File tree

3 files changed

+40
-31
lines changed

3 files changed

+40
-31
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- This ensures correct resource loading in environments like Spring Boot where the thread context classloader is used for resource loading.
1616
- Improve low memory breadcrumb capturing ([#4325](https://github.com/getsentry/sentry-java/pull/4325))
1717
- Fix do not initialize SDK for Jetpack Compose Preview builds ([#4324](https://github.com/getsentry/sentry-java/pull/4324))
18+
- Fix Synchronize Baggage values ([#4327](https://github.com/getsentry/sentry-java/pull/4327))
1819

1920
## 8.7.0
2021

sentry/api/sentry.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public abstract interface class io/sentry/BackfillingEventProcessor : io/sentry/
3535
public final class io/sentry/Baggage {
3636
public fun <init> (Lio/sentry/Baggage;)V
3737
public fun <init> (Lio/sentry/ILogger;)V
38-
public fun <init> (Ljava/util/Map;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/String;ZZLio/sentry/ILogger;)V
38+
public fun <init> (Ljava/util/concurrent/ConcurrentHashMap;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/String;ZZLio/sentry/ILogger;)V
3939
public fun forceSetSampleRate (Ljava/lang/Double;)V
4040
public fun freeze ()V
4141
public static fun fromEvent (Lio/sentry/SentryEvent;Lio/sentry/SentryOptions;)Lio/sentry/Baggage;

sentry/src/main/java/io/sentry/Baggage.java

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import io.sentry.protocol.SentryId;
66
import io.sentry.protocol.TransactionNameSource;
7+
import io.sentry.util.AutoClosableReentrantLock;
78
import io.sentry.util.SampleRateUtils;
89
import io.sentry.util.StringUtils;
910
import java.io.UnsupportedEncodingException;
@@ -13,7 +14,7 @@
1314
import java.text.DecimalFormatSymbols;
1415
import java.util.ArrayList;
1516
import java.util.Arrays;
16-
import java.util.HashMap;
17+
import java.util.Collections;
1718
import java.util.List;
1819
import java.util.Locale;
1920
import java.util.Map;
@@ -44,13 +45,15 @@ protected DecimalFormat initialValue() {
4445
private static final DecimalFormatterThreadLocal decimalFormatter =
4546
new DecimalFormatterThreadLocal();
4647

47-
final @NotNull Map<String, String> keyValues;
48-
@Nullable Double sampleRate;
49-
@Nullable Double sampleRand;
48+
private final @NotNull ConcurrentHashMap<String, String> keyValues;
49+
private final @NotNull AutoClosableReentrantLock keyValuesLock = new AutoClosableReentrantLock();
5050

51-
final @Nullable String thirdPartyHeader;
51+
private @Nullable Double sampleRate;
52+
private @Nullable Double sampleRand;
53+
54+
private final @Nullable String thirdPartyHeader;
5255
private boolean mutable;
53-
private boolean shouldFreeze;
56+
private final boolean shouldFreeze;
5457
final @NotNull ILogger logger;
5558

5659
@NotNull
@@ -99,7 +102,9 @@ public static Baggage fromHeader(
99102
final @Nullable String headerValue,
100103
final boolean includeThirdPartyValues,
101104
final @NotNull ILogger logger) {
102-
final @NotNull Map<String, String> keyValues = new HashMap<>();
105+
106+
final @NotNull ConcurrentHashMap<String, String> keyValues = new ConcurrentHashMap<>();
107+
103108
final @NotNull List<String> thirdPartyKeyValueStrings = new ArrayList<>();
104109
boolean shouldFreeze = false;
105110

@@ -196,7 +201,7 @@ public static Baggage fromEvent(
196201

197202
@ApiStatus.Internal
198203
public Baggage(final @NotNull ILogger logger) {
199-
this(new HashMap<>(), null, null, null, true, false, logger);
204+
this(new ConcurrentHashMap<>(), null, null, null, true, false, logger);
200205
}
201206

202207
@ApiStatus.Internal
@@ -213,12 +218,12 @@ public Baggage(final @NotNull Baggage baggage) {
213218

214219
@ApiStatus.Internal
215220
public Baggage(
216-
final @NotNull Map<String, String> keyValues,
221+
final @NotNull ConcurrentHashMap<String, String> keyValues,
217222
final @Nullable Double sampleRate,
218223
final @Nullable Double sampleRand,
219224
final @Nullable String thirdPartyHeader,
220-
boolean isMutable,
221-
boolean shouldFreeze,
225+
final boolean isMutable,
226+
final boolean shouldFreeze,
222227
final @NotNull ILogger logger) {
223228
this.keyValues = keyValues;
224229
this.sampleRate = sampleRate;
@@ -260,7 +265,10 @@ public String getThirdPartyHeader() {
260265
separator = ",";
261266
}
262267

263-
final Set<String> keys = new TreeSet<>(keyValues.keySet());
268+
final Set<String> keys;
269+
try (final @NotNull ISentryLifecycleToken ignored = keyValuesLock.acquire()) {
270+
keys = new TreeSet<>(Collections.list(keyValues.keys()));
271+
}
264272
keys.add(DSCKeys.SAMPLE_RATE);
265273
keys.add(DSCKeys.SAMPLE_RAND);
266274

@@ -440,38 +448,38 @@ public void setReplayId(final @Nullable String replayId) {
440448
set(DSCKeys.REPLAY_ID, replayId);
441449
}
442450

443-
@ApiStatus.Internal
444-
public void set(final @NotNull String key, final @Nullable String value) {
445-
set(key, value, false);
446-
}
447-
448451
/**
449-
* Sets / updates a value
452+
* Sets / updates a value, but only if the baggage is still mutable.
450453
*
451454
* @param key key
452455
* @param value value to set
453-
* @param force ignores mutability of this baggage and sets the value anyways
454456
*/
455-
private void set(final @NotNull String key, final @Nullable String value, final boolean force) {
456-
if (mutable || force) {
457-
this.keyValues.put(key, value);
457+
@ApiStatus.Internal
458+
public void set(final @NotNull String key, final @Nullable String value) {
459+
if (mutable) {
460+
if (value == null) {
461+
keyValues.remove(key);
462+
} else {
463+
keyValues.put(key, value);
464+
}
458465
}
459466
}
460467

461468
@ApiStatus.Internal
462469
public @NotNull Map<String, Object> getUnknown() {
463470
final @NotNull Map<String, Object> unknown = new ConcurrentHashMap<>();
464-
for (Map.Entry<String, String> keyValue : this.keyValues.entrySet()) {
465-
final @NotNull String key = keyValue.getKey();
466-
final @Nullable String value = keyValue.getValue();
467-
if (!DSCKeys.ALL.contains(key)) {
468-
if (value != null) {
469-
final @NotNull String unknownKey = key.replaceFirst(SENTRY_BAGGAGE_PREFIX, "");
470-
unknown.put(unknownKey, value);
471+
try (final @NotNull ISentryLifecycleToken ignored = keyValuesLock.acquire()) {
472+
for (final Map.Entry<String, String> keyValue : keyValues.entrySet()) {
473+
final @NotNull String key = keyValue.getKey();
474+
final @Nullable String value = keyValue.getValue();
475+
if (!DSCKeys.ALL.contains(key)) {
476+
if (value != null) {
477+
final @NotNull String unknownKey = key.replaceFirst(SENTRY_BAGGAGE_PREFIX, "");
478+
unknown.put(unknownKey, value);
479+
}
471480
}
472481
}
473482
}
474-
475483
return unknown;
476484
}
477485

0 commit comments

Comments
 (0)