Skip to content

Commit

Permalink
Add Option Params Into Sync Core Apis (#219)
Browse files Browse the repository at this point in the history
Added optional params to indicate disableExposureLogging etc. into new
set of core apis.
  • Loading branch information
weihao-statsig committed Feb 8, 2024
1 parent 96d098b commit bec55f6
Show file tree
Hide file tree
Showing 17 changed files with 209 additions and 31 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file added src/.DS_Store
Binary file not shown.
Binary file added src/main/.DS_Store
Binary file not shown.
Binary file added src/main/kotlin/.DS_Store
Binary file not shown.
Binary file added src/main/kotlin/com/.DS_Store
Binary file not shown.
Binary file modified src/main/kotlin/com/statsig/.DS_Store
Binary file not shown.
24 changes: 16 additions & 8 deletions src/main/kotlin/com/statsig/sdk/Statsig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ class Statsig {
*
* @param user A StatsigUser object used for evaluation
* @param gateName The name of the gate being evaluated
* @param option advanced setup for checkGate, for example disable exposure logging
*/
@JvmStatic
fun checkGateSync(user: StatsigUser, gateName: String): Boolean {
@JvmOverloads
fun checkGateSync(user: StatsigUser, gateName: String, option: CheckGateOptions? = null): Boolean {
if (!checkInitialized()) {
return false
}
return statsigServer.checkGateSync(user, gateName)
return statsigServer.checkGateSync(user, gateName, option)
}

/**
Expand Down Expand Up @@ -93,14 +95,16 @@ class Statsig {
*
* @param user A StatsigUser object used for evaluation
* @param dynamicConfigName The name of the DynamicConfig
* @param option advanced setup for getConfig, for example disable exposure logging
* @return DynamicConfig object evaluated for the selected StatsigUser
*/
@JvmStatic
fun getConfigSync(user: StatsigUser, dynamicConfigName: String): DynamicConfig {
@JvmOverloads
fun getConfigSync(user: StatsigUser, dynamicConfigName: String, option: GetConfigOptions? = null): DynamicConfig {
if (!checkInitialized()) {
return DynamicConfig.empty(dynamicConfigName)
}
return statsigServer.getConfigSync(user, dynamicConfigName)
return statsigServer.getConfigSync(user, dynamicConfigName, option)
}

/**
Expand Down Expand Up @@ -152,14 +156,16 @@ class Statsig {
*
* @param user A StatsigUser object used for the evaluation
* @param experimentName The name of the experiment
* @param option advanced setup for getExperiment, for example disable exposure logging
* @return DynamicConfig object evaluated for the selected StatsigUser
*/
@JvmStatic
fun getExperimentSync(user: StatsigUser, experimentName: String): DynamicConfig {
@JvmOverloads
fun getExperimentSync(user: StatsigUser, experimentName: String, option: GetExperimentOptions? = null): DynamicConfig {
if (!checkInitialized()) {
return DynamicConfig.empty(experimentName)
}
return statsigServer.getExperimentSync(user, experimentName)
return statsigServer.getExperimentSync(user, experimentName, option)
}

/**
Expand Down Expand Up @@ -201,14 +207,16 @@ class Statsig {
*
* @param user A StatsigUser object used for the evaluation
* @param layerName The name of the layer
* @param option advanced setup for getLayer, for example disable exposure logging
* @return Layer object evaluated for the selected StatsigUser
*/
@JvmStatic
fun getLayerSync(user: StatsigUser, layerName: String): Layer {
@JvmOverloads
fun getLayerSync(user: StatsigUser, layerName: String, option: GetLayerOptions? = null): Layer {
if (!checkInitialized()) {
return Layer.empty(layerName)
}
return statsigServer.getLayerSync(user, layerName)
return statsigServer.getLayerSync(user, layerName, option)
}

/**
Expand Down
16 changes: 16 additions & 0 deletions src/main/kotlin/com/statsig/sdk/StatsigOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,19 @@ class StatsigOptions(
)
}
}

data class CheckGateOptions(var disableExposureLogging: Boolean = false) {
constructor() : this(false)
}

data class GetConfigOptions(var disableExposureLogging: Boolean = false) {
constructor() : this(false)
}

data class GetLayerOptions(var disableExposureLogging: Boolean = false) {
constructor() : this(false)
}

data class GetExperimentOptions(var disableExposureLogging: Boolean = false) {
constructor() : this(false)
}
30 changes: 20 additions & 10 deletions src/main/kotlin/com/statsig/sdk/StatsigServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ sealed class StatsigServer {

abstract fun checkGateAsync(user: StatsigUser, gateName: String): CompletableFuture<Boolean>

abstract fun checkGateSync(user: StatsigUser, layerName: String): Boolean
abstract fun checkGateSync(user: StatsigUser, layerName: String, option: CheckGateOptions? = null): Boolean

abstract fun checkGateWithExposureLoggingDisabledAsync(user: StatsigUser, gateName: String): CompletableFuture<Boolean>

Expand All @@ -123,7 +123,8 @@ sealed class StatsigServer {

abstract fun getConfigSync(
user: StatsigUser,
dynamicConfigName: String
dynamicConfigName: String,
option: GetConfigOptions? = null
): DynamicConfig

abstract fun getConfigWithExposureLoggingDisabledAsync(
Expand All @@ -139,6 +140,7 @@ sealed class StatsigServer {
abstract fun getExperimentSync(
user: StatsigUser,
experimentName: String,
option: GetExperimentOptions? = null
): DynamicConfig

abstract fun getExperimentWithExposureLoggingDisabledAsync(
Expand All @@ -160,6 +162,7 @@ sealed class StatsigServer {
abstract fun getLayerSync(
user: StatsigUser,
layerName: String,
option: GetLayerOptions? = null
): Layer

abstract fun getLayerWithExposureLoggingDisabledAsync(
Expand Down Expand Up @@ -264,10 +267,12 @@ private class StatsigServerImpl() :
}, { return@capture false }, configName = gateName)
}

override fun checkGateSync(user: StatsigUser, gateName: String): Boolean {
override fun checkGateSync(user: StatsigUser, gateName: String, option: CheckGateOptions?): Boolean {
return errorBoundary.captureSync("checkGateSync", {
val result = checkGateImpl(user, gateName)
logGateExposureImpl(user, gateName, result)
if (option?.disableExposureLogging !== true) {
logGateExposureImpl(user, gateName, result)
}
return@captureSync result.booleanValue
}, { return@captureSync false }, configName = gateName)
}
Expand Down Expand Up @@ -321,14 +326,16 @@ private class StatsigServerImpl() :
}, configName = dynamicConfigName)
}

override fun getConfigSync(user: StatsigUser, dynamicConfigName: String): DynamicConfig {
override fun getConfigSync(user: StatsigUser, dynamicConfigName: String, option: GetConfigOptions?): DynamicConfig {
if (!isSDKInitialized()) {
return DynamicConfig.empty(dynamicConfigName)
}
return this.errorBoundary.captureSync("getConfigSync", {
val normalizedUser = normalizeUser(user)
val result = getConfigImpl(user, dynamicConfigName)
logConfigImpl(normalizedUser, dynamicConfigName, result)
if (option?.disableExposureLogging !== true) {
logConfigImpl(normalizedUser, dynamicConfigName, result)
}
return@captureSync getDynamicConfigFromEvalResult(result, dynamicConfigName)
}, {
return@captureSync DynamicConfig.empty(dynamicConfigName)
Expand Down Expand Up @@ -370,14 +377,16 @@ private class StatsigServerImpl() :
}, configName = experimentName)
}

override fun getExperimentSync(user: StatsigUser, experimentName: String): DynamicConfig {
override fun getExperimentSync(user: StatsigUser, experimentName: String, option: GetExperimentOptions?): DynamicConfig {
if (!isSDKInitialized()) {
return DynamicConfig.empty(experimentName)
}
return this.errorBoundary.captureSync("getExperimentSync", {
val normalizedUser = normalizeUser(user)
val result = getConfigImpl(user, experimentName)
logConfigImpl(normalizedUser, experimentName, result)
if (option?.disableExposureLogging !== true) {
logConfigImpl(normalizedUser, experimentName, result)
}
return@captureSync getDynamicConfigFromEvalResult(result, experimentName)
}, {
return@captureSync DynamicConfig.empty(experimentName)
Expand Down Expand Up @@ -445,9 +454,10 @@ private class StatsigServerImpl() :
}, configName = layerName)
}

override fun getLayerSync(user: StatsigUser, layerName: String): Layer {
override fun getLayerSync(user: StatsigUser, layerName: String, option: GetLayerOptions?): Layer {
return this.errorBoundary.captureSync("getLayerSync", {
return@captureSync getLayerImpl(user, layerName, false)
val disableExposureLogging = option?.disableExposureLogging == true
return@captureSync getLayerImpl(user, layerName, disableExposureLogging)
}, {
return@captureSync Layer.empty(layerName)
}, configName = layerName)
Expand Down
Binary file added src/test/.DS_Store
Binary file not shown.
Binary file added src/test/java/.DS_Store
Binary file not shown.
Binary file added src/test/java/com/.DS_Store
Binary file not shown.
Binary file added src/test/java/com/statsig/.DS_Store
Binary file not shown.
131 changes: 131 additions & 0 deletions src/test/java/com/statsig/sdk/ExposureLoggingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,38 @@ class ExposureLoggingTest {
assertEquals(0, events.size)
}

@Test
fun testCheckGateSyncWithExposureLoggingDisabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = CheckGateOptions(true)
driver.checkGateSync(user, "a_gate", setExposureLoggingDisabled)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(0, events.size)
}

@Test
fun testCheckGateSyncWithExposureLoggingEnabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = CheckGateOptions(false)
driver.checkGateSync(user, "a_gate", setExposureLoggingDisabled) // default
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testCheckGateSyncWithExposureLoggingDefault() = runBlocking {
driver.initialize("secret-local", options)
driver.checkGateSync(user, "a_gate") // default
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testManuallyLogGateExposure() = runBlocking {
driver.initialize("secret-local", options)
Expand Down Expand Up @@ -125,6 +157,38 @@ class ExposureLoggingTest {
assertEquals(1, events.size)
}

@Test
fun testGetConfigSyncWithExposureLoggingDisabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = GetConfigOptions(true)
driver.getConfigSync(user, "a_config", setExposureLoggingDisabled)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(0, events.size)
}

@Test
fun testGetConfigSyncWithExposureLoggingEnabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = GetConfigOptions(false)
driver.getConfigSync(user, "a_config", setExposureLoggingDisabled)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testGetConfigSyncWithExposureLoggingDefault() = runBlocking {
driver.initialize("secret-local", options)
driver.getConfigSync(user, "a_config")
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testManualLogConfigExposure() = runBlocking {
driver.initialize("secret-local", options)
Expand Down Expand Up @@ -156,6 +220,38 @@ class ExposureLoggingTest {
assertEquals(1, events.size)
}

@Test
fun testGetExperimentSyncWithExposureLoggingDisabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = GetExperimentOptions(true)
driver.getExperimentSync(user, "a_config", setExposureLoggingDisabled)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(0, events.size)
}

@Test
fun testGetExperimentSyncWithExposureLoggingEnabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = GetExperimentOptions(false)
driver.getExperimentSync(user, "a_config", setExposureLoggingDisabled)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testGetExperimentSyncWithExposureLoggingDefault() = runBlocking {
driver.initialize("secret-local", options)
driver.getExperimentSync(user, "a_config")
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testGetLayerWithExposureLoggingDisabled() = runBlocking {
driver.initialize("secret-local", options)
Expand All @@ -177,4 +273,39 @@ class ExposureLoggingTest {
val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testGetLayerSyncWithExposureLoggingDisabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = GetLayerOptions(true)
val layer = driver.getLayerSync(user, "explicit_vs_implicit_parameter_layer", setExposureLoggingDisabled)
layer.getInt("an_int", 0)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(0, events.size)
}

@Test
fun testGetLayerSyncWithExposureLoggingEnabled() = runBlocking {
driver.initialize("secret-local", options)
val setExposureLoggingDisabled = GetLayerOptions(false)
val layer = driver.getLayerSync(user, "explicit_vs_implicit_parameter_layer", setExposureLoggingDisabled)
layer.getInt("an_int", 0)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}

@Test
fun testGetLayerSyncWithExposureLoggingDefault() = runBlocking {
driver.initialize("secret-local", options)
val layer = driver.getLayerSync(user, "explicit_vs_implicit_parameter_layer")
layer.getInt("an_int", 0)
driver.shutdown()

val events = captureEvents(eventLogInputCompletable)
assertEquals(1, events.size)
}
}
4 changes: 3 additions & 1 deletion src/test/java/com/statsig/sdk/LayerInJavaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ public void testLayer() throws Exception {
CompletableFuture<Layer> futureLayer = driver.getLayerAsync(user, "empty_layer");
Layer layer = futureLayer.get();

Layer getLayerSyncRes = driver.getLayerSync(user, "empty_layer");
Layer getLayerSyncRes = driver.getLayerSync(user, "empty_layer", new GetLayerOptions());
Layer getLayerSyncWithoutOption = driver.getLayerSync(user, "empty_layer", null);

assertEquals(layer.getBoolean("default_bool", true), true);
assertEquals(getLayerSyncRes.getBoolean("default_bool", true), true);
assertEquals(getLayerSyncWithoutOption.getBoolean("default_bool", true), true);
}
}
Loading

0 comments on commit bec55f6

Please sign in to comment.