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 docs/changelog/133004.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 133004
summary: Limit frequency of feature last-used time updates
area: License
type: bug
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,13 @@ public String statusDescription() {

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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,13 @@ public void testLastUsedMomentaryFeature() {
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() {
Expand Down