From b03b114853e405190bfc43e91e257378f2b6d6fd Mon Sep 17 00:00:00 2001 From: Caroline6312 Date: Mon, 29 Dec 2025 13:59:50 -0800 Subject: [PATCH 1/3] Add metrics for the number of optout records --- src/main/java/com/uid2/operator/Const.java | 1 + .../operator/store/CloudSyncOptOutStore.java | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/main/java/com/uid2/operator/Const.java b/src/main/java/com/uid2/operator/Const.java index 9d994cd07..14f878371 100644 --- a/src/main/java/com/uid2/operator/Const.java +++ b/src/main/java/com/uid2/operator/Const.java @@ -28,6 +28,7 @@ public class Config extends com.uid2.shared.Const.Config { public static final String GcpSecretVersionNameProp = "gcp_secret_version_name"; public static final String OptOutStatusApiEnabled = "optout_status_api_enabled"; public static final String OptOutStatusMaxRequestSize = "optout_status_max_request_size"; + public static final String OptOutOldCountThresholdSecondsProp = "optout_old_count_threshold_seconds"; public static final String MaxInvalidPaths = "logging_limit_max_invalid_paths_per_interval"; public static final String MaxVersionBucketsPerSite = "logging_limit_max_version_buckets_per_site"; diff --git a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java index 3da6531be..ed0a093f4 100644 --- a/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java +++ b/src/main/java/com/uid2/operator/store/CloudSyncOptOutStore.java @@ -381,12 +381,18 @@ public static class OptOutStoreSnapshot { .description("gauge for max entries can be cached in bloomfilter") .register(Metrics.globalRegistry); + private static final Gauge GAUGE_OPTOUT_OLD_COUNT = Gauge + .builder("uid2_operator_optout_old_count", () -> OptOutStoreSnapshot.oldCount.get()) + .description("gauge for number of unique optout entries older than threshold (configurable)") + .register(Metrics.globalRegistry); + // stores the timestamp of last updated delta or partition file private static final AtomicReference lastUpdatedTimestamp = new AtomicReference<>(Instant.EPOCH); private static final AtomicLong bloomFilterSize = new AtomicLong(0); private static final AtomicLong bloomFilterMax = new AtomicLong(0); private static final AtomicLong totalEntries = new AtomicLong(0); private static final AtomicInteger adIdCount = new AtomicInteger(0); + private static final AtomicLong oldCount = new AtomicLong(0); private static final BiFunction OPT_OUT_TIMESTAMP_MERGE_STRATEGY = Long::min; private final DownloadCloudStorage fsLocal; @@ -418,6 +424,8 @@ public static class OptOutStoreSnapshot { private final Clock clock; + private final long optOutOldCountThresholdSeconds; + public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, Clock clock) { this.clock = clock; this.fsLocal = fsLocal; @@ -436,6 +444,7 @@ public OptOutStoreSnapshot(DownloadCloudStorage fsLocal, JsonObject jsonConfig, this.adIdToOptOutTimestamp = Collections.emptyMap(); this.optoutStatusApiEnabled = jsonConfig.getBoolean(Const.Config.OptOutStatusApiEnabled, true); + this.optOutOldCountThresholdSeconds = jsonConfig.getLong(Const.Config.OptOutOldCountThresholdSecondsProp, 3600L); // Default 1 hour // initially 1 partition this.partitions = new OptOutPartition[1]; @@ -453,6 +462,7 @@ public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap this.fsLocal = last.fsLocal; this.fileUtils = last.fileUtils; this.iteration = last.iteration + 1; + this.optOutOldCountThresholdSeconds = last.optOutOldCountThresholdSeconds; this.bloomFilter = bf; this.heap = heap; @@ -481,6 +491,7 @@ public OptOutStoreSnapshot(OptOutStoreSnapshot last, BloomFilter bf, OptOutHeap // update total entries totalEntries.set(size()); adIdCount.set(this.adIdToOptOutTimestamp.size()); + oldCount.set(countOldRecords(this.optOutOldCountThresholdSeconds)); } public long size() { @@ -490,6 +501,22 @@ public long size() { .sum(); } + public long countOldRecords(long thresholdSeconds) { + long currentTimeSeconds = clock.instant().getEpochSecond(); + long cutoffTime = currentTimeSeconds - thresholdSeconds; + + Set uniqueHashes = new HashSet<>(); + for (OptOutPartition partition : this.partitions) { + if (partition == null) continue; + partition.forEach(entry -> { + if (entry.timestamp < cutoffTime) { + uniqueHashes.add(entry.idHashToB64()); + } + }); + } + return uniqueHashes.size(); + } + // method provided for OptOutService to assess health public boolean isHealthy(Instant now) { // index is healthy if it is updated within 3 * logRotationInterval From 25737bb510b30a322f39db357a3921f5cd25804a Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Wed, 31 Dec 2025 01:06:53 +0000 Subject: [PATCH 2/3] [CI Pipeline] Released Snapshot version: 5.62.39-alpha-272-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f57a849e1..bac81eeb6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.62.38 + 5.62.39-alpha-272-SNAPSHOT UTF-8 From dd47914118cc9c45ba2d5fd8ea3fe2178b8109ed Mon Sep 17 00:00:00 2001 From: caroline-ttd <157654071+caroline-ttd@users.noreply.github.com> Date: Tue, 6 Jan 2026 13:22:55 -0800 Subject: [PATCH 3/3] Remove extra newline in pom.xml --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index e0a7df6f7..b26d075e5 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,6 @@ com.uid2 uid2-operator 5.62.48 - UTF-8