mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 02:48:03 +01:00
Add finer grain rollouts to experiments
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
package org.whispersystems.textsecuregcm.configuration.dynamic;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Max;
|
||||
@@ -16,21 +17,52 @@ import java.util.UUID;
|
||||
|
||||
public class DynamicExperimentEnrollmentConfiguration {
|
||||
|
||||
public static class UuidSelector {
|
||||
|
||||
@JsonProperty
|
||||
@Valid
|
||||
private Set<UUID> enrolledUuids = Collections.emptySet();
|
||||
private Set<UUID> uuids = Collections.emptySet();
|
||||
|
||||
/**
|
||||
* What percentage of enrolled UUIDs should the experiment be enabled for.
|
||||
* <p>
|
||||
* Unlike {@link this#enrollmentPercentage}, this is not stable by UUID. The same UUID may be
|
||||
* enrolled/unenrolled across calls.
|
||||
*/
|
||||
@JsonProperty
|
||||
@Valid
|
||||
@Min(0)
|
||||
@Max(100)
|
||||
private int enrollmentPercentage = 0;
|
||||
private int uuidEnrollmentPercentage = 100;
|
||||
|
||||
public Set<UUID> getEnrolledUuids() {
|
||||
return enrolledUuids;
|
||||
public Set<UUID> getUuids() {
|
||||
return uuids;
|
||||
}
|
||||
|
||||
public int getEnrollmentPercentage() {
|
||||
return enrollmentPercentage;
|
||||
public int getUuidEnrollmentPercentage() {
|
||||
return uuidEnrollmentPercentage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private UuidSelector uuidSelector = new UuidSelector();
|
||||
|
||||
/**
|
||||
* If the UUID is not enrolled via {@link UuidSelector#uuids}, what is the percentage chance it should be enrolled.
|
||||
* <p>
|
||||
* This is stable by UUID, for a given configuration if a UUID is enrolled it will always be enrolled on every call.
|
||||
*/
|
||||
@JsonProperty
|
||||
@Valid
|
||||
@Min(0)
|
||||
@Max(100)
|
||||
private int enrollmentPercentage = 0;
|
||||
|
||||
public int getEnrollmentPercentage() {
|
||||
return enrollmentPercentage;
|
||||
}
|
||||
|
||||
public UuidSelector getUuidSelector() {
|
||||
return uuidSelector;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
package org.whispersystems.textsecuregcm.experiment;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicExperimentEnrollmentConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicPreRegistrationExperimentEnrollmentConfiguration;
|
||||
@@ -16,9 +19,20 @@ import org.whispersystems.textsecuregcm.util.Util;
|
||||
public class ExperimentEnrollmentManager {
|
||||
|
||||
private final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
||||
private final Random random;
|
||||
|
||||
public ExperimentEnrollmentManager(final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
||||
|
||||
public ExperimentEnrollmentManager(
|
||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
||||
this(dynamicConfigurationManager, ThreadLocalRandom.current());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ExperimentEnrollmentManager(
|
||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager,
|
||||
final Random random) {
|
||||
this.dynamicConfigurationManager = dynamicConfigurationManager;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public boolean isEnrolled(final UUID accountUuid, final String experimentName) {
|
||||
@@ -28,8 +42,9 @@ public class ExperimentEnrollmentManager {
|
||||
|
||||
return maybeConfiguration.map(config -> {
|
||||
|
||||
if (config.getEnrolledUuids().contains(accountUuid)) {
|
||||
return true;
|
||||
if (config.getUuidSelector().getUuids().contains(accountUuid)) {
|
||||
final int r = random.nextInt(100);
|
||||
return r < config.getUuidSelector().getUuidEnrollmentPercentage();
|
||||
}
|
||||
|
||||
return isEnrolled(accountUuid, config.getEnrollmentPercentage(), experimentName);
|
||||
|
||||
Reference in New Issue
Block a user