Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sets evaluation in clients #533

Merged
merged 1 commit into from
Sep 7, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Useful for testing
*
*/
public class AlwaysReturnControlSplitClient implements io.split.android.client.SplitClient {
public class AlwaysReturnControlSplitClient implements SplitClient {

@Override
public String getTreatment(String featureFlagName) {
Expand Down Expand Up @@ -62,22 +62,22 @@ public SplitResult getTreatmentWithConfig(String featureFlagName, Map<String, Ob

@Override
public Map<String, String> getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
return Collections.emptyMap(); //TODO
return Collections.emptyMap();
}

@Override
public Map<String, String> getTreatmentsByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
return Collections.emptyMap(); //TODO
return Collections.emptyMap();
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
return Collections.emptyMap(); //TODO
return Collections.emptyMap();
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
return Collections.emptyMap(); //TODO
return Collections.emptyMap();
}

@Override
Expand Down
24 changes: 4 additions & 20 deletions src/main/java/io/split/android/client/SplitClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,38 +190,22 @@ public Map<String, SplitResult> getTreatmentsWithConfig(List<String> featureFlag

@Override
public Map<String, String> getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
try {
return Collections.emptyMap(); //TODO
} catch (Exception exception) {
return null;
}
return mTreatmentManager.getTreatmentsByFlagSet(flagSet, attributes, mIsClientDestroyed);
}

@Override
public Map<String, String> getTreatmentsByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
try {
return Collections.emptyMap(); //TODO
} catch (Exception exception) {
return null;
}
return mTreatmentManager.getTreatmentsByFlagSets(flagSets, attributes, mIsClientDestroyed);
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
try {
return Collections.emptyMap(); //TODO
} catch (Exception exception) {
return null;
}
return mTreatmentManager.getTreatmentsWithConfigByFlagSet(flagSet, attributes, mIsClientDestroyed);
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
try {
return Collections.emptyMap(); //TODO
} catch (Exception exception) {
return null;
}
return mTreatmentManager.getTreatmentsWithConfigByFlagSets(flagSets, attributes, mIsClientDestroyed);
}

public void on(SplitEvent event, SplitEventTask task) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import androidx.annotation.Nullable;

import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -46,9 +47,9 @@ public final class LocalhostSplitClient implements SplitClient {
private final WeakReference<SplitClientContainer> mClientContainer;
private final Key mKey;
private final SplitEventsManager mEventsManager;
private final Evaluator mEvaluator;
private final TreatmentManager mTreatmentManager;
private boolean mIsClientDestroyed = false;
private final SplitsStorage mSplitsStorage;

public LocalhostSplitClient(@NonNull LocalhostSplitFactory container,
@NonNull SplitClientContainer clientContainer,
Expand All @@ -66,9 +67,9 @@ public LocalhostSplitClient(@NonNull LocalhostSplitFactory container,
mClientContainer = new WeakReference<>(checkNotNull(clientContainer));
mKey = checkNotNull(key);
mEventsManager = checkNotNull(eventsManager);
mEvaluator = new EvaluatorImpl(splitsStorage, splitParser);
mSplitsStorage = splitsStorage;
mTreatmentManager = new TreatmentManagerImpl(mKey.matchingKey(), mKey.bucketingKey(),
mEvaluator, new KeyValidatorImpl(),
new EvaluatorImpl(splitsStorage, splitParser), new KeyValidatorImpl(),
new SplitValidatorImpl(), getImpressionsListener(splitClientConfig),
splitClientConfig.labelsEnabled(), eventsManager, attributesManager, attributesMerger,
telemetryStorageProducer, configuredFlagSets, splitsStorage);
Expand Down Expand Up @@ -143,22 +144,70 @@ public Map<String, SplitResult> getTreatmentsWithConfig(List<String> featureFlag

@Override
public Map<String, String> getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
return null;
try {
return mTreatmentManager.getTreatmentsByFlagSet(flagSet, attributes, mIsClientDestroyed);
} catch (Exception exception) {
Logger.e(exception);

Map<String, String> result = new HashMap<>();
Set<String> namesByFlagSets = mSplitsStorage.getNamesByFlagSets(Collections.singletonList(flagSet));
for (String featureFlagName : namesByFlagSets) {
result.put(featureFlagName, Treatments.CONTROL);
}

return result;
}
}

@Override
public Map<String, String> getTreatmentsByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
return null;
try {
return mTreatmentManager.getTreatmentsByFlagSets(flagSets, attributes, mIsClientDestroyed);
} catch (Exception exception) {
gthea marked this conversation as resolved.
Show resolved Hide resolved
Logger.e(exception);

Map<String, String> result = new HashMap<>();
Set<String> namesByFlagSets = mSplitsStorage.getNamesByFlagSets(flagSets);
for (String featureFlagName : namesByFlagSets) {
result.put(featureFlagName, Treatments.CONTROL);
}

return result;
}
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
return null;
try {
return mTreatmentManager.getTreatmentsWithConfigByFlagSet(flagSet, attributes, mIsClientDestroyed);
} catch (Exception exception) {
Logger.e(exception);

Map<String, SplitResult> result = new HashMap<>();
Set<String> namesByFlagSets = mSplitsStorage.getNamesByFlagSets(Collections.singletonList(flagSet));
for (String featureFlagName : namesByFlagSets) {
result.put(featureFlagName, new SplitResult(Treatments.CONTROL));
}

return result;
}
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
return null;
try {
return mTreatmentManager.getTreatmentsWithConfigByFlagSets(flagSets, attributes, mIsClientDestroyed);
} catch (Exception exception) {
Logger.e(exception);

Map<String, SplitResult> result = new HashMap<>();
Set<String> namesByFlagSets = mSplitsStorage.getNamesByFlagSets(flagSets);
for (String featureFlagName : namesByFlagSets) {
result.put(featureFlagName, new SplitResult(Treatments.CONTROL));
}

return result;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,68 +183,100 @@ public Map<String, SplitResult> getTreatmentsWithConfig(List<String> splits, Map
@Override
public Map<String, String> getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes, boolean isClientDestroyed) {
String validationTag = ValidationTag.GET_TREATMENTS_BY_FLAG_SET;
Set<String> names = getNamesFromSet(validationTag, Collections.singletonList(flagSet));
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplits(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
Set<String> names = new HashSet<>();
try {
return evaluateFeatures(names, attributes, validationTag, SplitResult::treatment);
} finally {
recordLatency(Method.TREATMENTS_BY_FLAG_SET, start);
names = getNamesFromSet(validationTag, Collections.singletonList(flagSet));
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplits(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
try {
return evaluateFeatures(names, attributes, validationTag, SplitResult::treatment);
} finally {
recordLatency(Method.TREATMENTS_BY_FLAG_SET, start);
}
} catch (Exception exception) {
Logger.e("Client getTreatmentsByFlagSet exception", exception);
mTelemetryStorageProducer.recordException(Method.TREATMENTS_BY_FLAG_SET);

return controlTreatmentsForSplits(new ArrayList<>(names), validationTag);
}
}

@Override
public Map<String, String> getTreatmentsByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes, boolean isClientDestroyed) {
String validationTag = ValidationTag.GET_TREATMENTS_BY_FLAG_SETS;
Set<String> names = getNamesFromSet(validationTag, flagSets);
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplits(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
Set<String> names = new HashSet<>();
try {
return evaluateFeatures(names, attributes, validationTag, SplitResult::treatment);
} finally {
recordLatency(Method.TREATMENTS_BY_FLAG_SETS, start);
names = getNamesFromSet(validationTag, flagSets);
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplits(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
try {
return evaluateFeatures(names, attributes, validationTag, SplitResult::treatment);
} finally {
recordLatency(Method.TREATMENTS_BY_FLAG_SETS, start);
}
} catch (Exception exception) {
Logger.e("Client getTreatmentsByFlagSets exception", exception);
mTelemetryStorageProducer.recordException(Method.TREATMENTS_BY_FLAG_SETS);

return controlTreatmentsForSplits(new ArrayList<>(names), validationTag);
}
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes, boolean isClientDestroyed) {
String validationTag = ValidationTag.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET;
Set<String> names = getNamesFromSet(validationTag, Collections.singletonList(flagSet));
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplitsWithConfig(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
Set<String> names = new HashSet<>();
try {
return evaluateFeatures(names, attributes, validationTag, ResultTransformer::identity);
} finally {
recordLatency(Method.TREATMENTS_WITH_CONFIG_BY_FLAG_SET, start);
names = getNamesFromSet(validationTag, Collections.singletonList(flagSet));
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplitsWithConfig(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
try {
return evaluateFeatures(names, attributes, validationTag, ResultTransformer::identity);
} finally {
recordLatency(Method.TREATMENTS_WITH_CONFIG_BY_FLAG_SET, start);
}
} catch (Exception exception) {
Logger.e("Client getTreatmentsWithConfigByFlagSet exception", exception);
mTelemetryStorageProducer.recordException(Method.TREATMENTS_WITH_CONFIG_BY_FLAG_SET);

return controlTreatmentsForSplitsWithConfig(new ArrayList<>(names), validationTag);
}
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes, boolean isClientDestroyed) {
String validationTag = ValidationTag.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS;
Set<String> names = getNamesFromSet(validationTag, flagSets);
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplitsWithConfig(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
Set<String> names = new HashSet<>();
try {
return evaluateFeatures(names, attributes, validationTag, ResultTransformer::identity);
} finally {
recordLatency(Method.TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, start);
names = getNamesFromSet(validationTag, flagSets);
if (isClientDestroyed) {
mValidationLogger.e(CLIENT_DESTROYED_MESSAGE, validationTag);
return controlTreatmentsForSplitsWithConfig(new ArrayList<>(names), validationTag);
}

long start = System.currentTimeMillis();
try {
return evaluateFeatures(names, attributes, validationTag, ResultTransformer::identity);
} finally {
recordLatency(Method.TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, start);
}
} catch (Exception exception) {
Logger.e("Client getTreatmentsWithConfigByFlagSets exception", exception);
mTelemetryStorageProducer.recordException(Method.TREATMENTS_WITH_CONFIG_BY_FLAG_SETS);

return controlTreatmentsForSplitsWithConfig(new ArrayList<>(names), validationTag);
}
}

Expand Down