Browse Source

Limit frequency of feature last-used time updates (#133004)

Joe Gallo 1 month ago
parent
commit
f248fd1ce3

+ 5 - 0
docs/changelog/133004.yaml

@@ -0,0 +1,5 @@
+pr: 133004
+summary: Limit frequency of feature last-used time updates
+area: License
+type: bug
+issues: []

+ 7 - 1
x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java

@@ -447,7 +447,13 @@ public class XPackLicenseState {
 
     void featureUsed(LicensedFeature feature) {
         checkExpiry();
-        usage.put(new FeatureUsage(feature, null), epochMillisProvider.getAsLong());
+        final long now = epochMillisProvider.getAsLong();
+        final FeatureUsage feat = new FeatureUsage(feature, null);
+        final Long mostRecent = usage.get(feat);
+        // only update if needed, to prevent ConcurrentHashMap lock-contention on writes
+        if (mostRecent == null || now > mostRecent) {
+            usage.put(feat, now);
+        }
     }
 
     void enableUsageTracking(LicensedFeature feature, String contextName) {

+ 7 - 0
x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java

@@ -244,6 +244,13 @@ public class XPackLicenseStateTests extends ESTestCase {
         lastUsed = licenseState.getLastUsed();
         assertThat("feature.check updates usage", lastUsed.keySet(), containsInAnyOrder(usage));
         assertThat(lastUsed.get(usage), equalTo(200L));
+
+        // updates to the last used timestamp only happen if the time has increased
+        currentTime.set(199);
+        goldFeature.check(licenseState);
+        lastUsed = licenseState.getLastUsed();
+        assertThat("feature.check updates usage", lastUsed.keySet(), containsInAnyOrder(usage));
+        assertThat(lastUsed.get(usage), equalTo(200L));
     }
 
     public void testLastUsedMomentaryFeatureWithSameNameDifferentFamily() {