Skip to content

Commit

Permalink
feat(feature-flags): support quota limiting for feature flags (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmarticus authored Feb 25, 2025
1 parent 41ac8e9 commit dc6b220
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Next

## 3.11.3 - 2025-02-25

- feat: support quota limiting for feature flags ([#228](https://github.com/PostHog/posthog-android/pull/228))

## 3.11.2 - 2025-02-04

- fix: touches fall back to single touches if out of bounds ([#221](https://github.com/PostHog/posthog-android/pull/221))
Expand Down
13 changes: 1 addition & 12 deletions posthog-android/lint-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

<issue
id="GradleDependency"
message="A newer version of androidx.compose.ui:ui than 1.0.0 is available: 1.7.7"
message="A newer version of androidx.compose.ui:ui than 1.0.0 is available: 1.7.8"
errorLine1=" compileOnly(&quot;androidx.compose.ui:ui:${PosthogBuildConfig.Dependencies.ANDROIDX_COMPOSE}&quot;)"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
Expand All @@ -45,15 +45,4 @@
column="17"/>
</issue>

<issue
id="GradleDependency"
message="A newer version of org.jetbrains.kotlin:kotlin-test-junit than 1.8.22 is available: 1.9.20"
errorLine1=" testImplementation(&quot;org.jetbrains.kotlin:kotlin-test-junit:${PosthogBuildConfig.Kotlin.KOTLIN}&quot;)"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="build.gradle.kts"
line="108"
column="24"/>
</issue>

</issues>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
* @property errorsWhileComputingFlags if there were errors computing feature flags
* @property featureFlags the feature flags
* @property featureFlagPayloads the feature flag payloads
* @property quotaLimited array of quota limited features
*/
@IgnoreJRERequirement
internal data class PostHogDecideResponse(
Expand All @@ -16,4 +17,5 @@ internal data class PostHogDecideResponse(
val featureFlagPayloads: Map<String, Any?>?,
// its either a boolean or a map, see https://github.com/PostHog/posthog-js/blob/10fd7f4fa083f997d31a4a4c7be7d311d0a95e74/src/types.ts#L235-L243
val sessionRecording: Any? = false,
val quotaLimited: List<String>? = null,
)
11 changes: 11 additions & 0 deletions posthog/src/main/java/com/posthog/internal/PostHogFeatureFlags.kt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ internal class PostHogFeatureFlags(

response?.let {
synchronized(featureFlagsLock) {
if (response.quotaLimited?.contains("feature_flags") == true) {
config.logger.log("Feature flags are quota limited, clearing existing flags")
this.featureFlags = null
this.featureFlagPayloads = null
config.cachePreferences?.let { preferences ->
preferences.remove(FEATURE_FLAGS)
preferences.remove(FEATURE_FLAGS_PAYLOAD)
}
return@let
}

if (response.errorsWhileComputingFlags) {
// if not all flags were computed, we upsert flags instead of replacing them
this.featureFlags =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,4 +434,49 @@ internal class PostHogFeatureFlagsTest {

sut.clear()
}

@Test
fun `clear flags when quota limited`() {
val http =
mockHttp(
response =
MockResponse().setBody(
"""
{
"featureFlags": {"flag1": true},
"featureFlagPayloads": {"flag1": "payload1"}
}
""".trimIndent(),
),
)
val url = http.url("/")
val sut = getSut(host = url.toString())

// Load initial flags
sut.loadFeatureFlags("test_id", null, null, null)
executor.awaitExecution()

// Verify flags are loaded
assertNotNull(sut.getFeatureFlags())
assertNotNull(preferences.getValue(FEATURE_FLAGS))

// Send quota limited response
http.enqueue(
MockResponse().setBody(
"""
{
"quotaLimited": ["feature_flags"]
}
""".trimIndent(),
),
)

// Reload flags
sut.loadFeatureFlags("test_id", null, null, null)
executor.awaitExecution()

// Verify flags are cleared
assertNull(sut.getFeatureFlags())
assertNull(preferences.getValue(FEATURE_FLAGS))
}
}

0 comments on commit dc6b220

Please sign in to comment.