Skip to content

[WIP] [POC] Use config endpoint for workflows#3666

Draft
vegaro wants to merge 1 commit into
phase_4__v2_config_topic_handler_registryfrom
cesar/config-workflows-spike
Draft

[WIP] [POC] Use config endpoint for workflows#3666
vegaro wants to merge 1 commit into
phase_4__v2_config_topic_handler_registryfrom
cesar/config-workflows-spike

Conversation

@vegaro

@vegaro vegaro commented Jun 26, 2026

Copy link
Copy Markdown
Member

No description provided.

@RevenueCat-Danger-Bot

RevenueCat-Danger-Bot commented Jun 26, 2026

Copy link
Copy Markdown
2 Errors
🚫 Label the PR using one of the change type labels. If you are not sure which label to use, choose pr:other.
🚫 This PR changes 895 lines of production Kotlin/Java code, over the 300-line limit. Split it into smaller PRs, or add the skip-pr-lines-changed-check label to bypass.
Label Description
pr:feat A new feature. Use along with pr:breaking to force a major release.
pr:fix A bug fix. Use along with pr:force_minor to force a minor release.
pr:other Other changes. Catch-all for anything that doesn't fit the above categories. Releases that only contain this label will not be released. Use along with pr:force_patch, or pr:force_minor to force a patch or minor release.
pr:RevenueCatUI Use along any other tag to mark a PR that only contains RevenueCatUI changes
pr:next_release Preparing a new release
pr:dependencies Updating a dependency
pr:phc_dependencies Updating purchases-hybrid-common dependency
pr:changelog_ignore The PR will not be included in the changelog. This label doesn't determine the type of bump of the version and must be combined with pr:feat, pr:fix or pr:other.

Generated by 🚫 Danger

@vegaro vegaro changed the base branch from main to phase_4__v2_config_topic_handler_registry June 26, 2026 13:34
@vegaro vegaro force-pushed the cesar/config-workflows-spike branch 4 times, most recently from f6837f6 to 4472d84 Compare June 26, 2026 14:42
@vegaro vegaro force-pushed the cesar/config-workflows-spike branch from 4472d84 to 8102036 Compare June 26, 2026 14:48

@tonidero tonidero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!! Only gave it a quick look but this is pretty much what I was thinking indeed! Still a lot of things left to do, but it's nice to have the skeleton with this 🙌 cc @RevenueCat/coresdk would be great for you to take a look as well to see if you find any issues with this architecture!


override fun clear() {
// No handler-owned state: the manager prunes this topic's persisted metadata when it leaves the
// active set, and blob retention drops any body it kept alive.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to support clearing I think, so we clear blobs upon a user change (since some of this will be user-dependent (at least that was my thinking)

fun workflowIdForOfferingId(offeringId: String): String? =
manager.topic(TOPIC_NAME)
?.entries
?.firstOrNull { (_, item) -> item.content.stringOrNull(KEY_OFFERING_IDENTIFIER) == offeringId }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I wonder if we should optimize this somehow... Maybe we could keep in memory a map of offering id to workflow id, so we could then access by id directly... but maybe I'm eagerly optimizing it... we should test with apps with a ton of offerings and workflows later on to make sure this works fine 🙏

// WorkflowsConfigProvider. The manager is hoisted so the orchestrator can drive its lifecycle
// (foreground refresh + teardown).
var remoteConfigManager: RemoteConfigManager? = null
val workflowManager = if (appConfig.useWorkflows) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to rename the feature flag to something more generic, since it will mean more than just workflows I guess... But not a blocker.

OfferingsConfigGate { appInBackground, appUserID, onReady ->
manager.awaitTopicsReady(listOf("workflows"), appInBackground, appUserID, onReady)
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting mehanism... I believe it should work 👍

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right! I find the gate function very elegant haha

suspend fun body(topicName: String, itemKey: String): ByteArray? {
awaitCurrentSync()
val item = topic(topicName)?.get(itemKey) ?: return null
val ref = item.blobRef ?: return item.content.toString().toByteArray()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I wonder if we want to just return back the item string in case blobRef is null.... I would consider this body to only return in case there is an actual blob associated. For the "metadata" part of the config, that probably needs to be fetched from the RemoteConfigTopicStore?

*/
internal fun interface RemoteConfigBlobFetcher {
/** Ensures [ref] is cached, returning whether it is now on disk. The default wiring is a no-op (`false`). */
suspend fun ensureDownloaded(ref: String): Boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will also need to add some prioritization system, so when we call this, the corresponding blob gets downloaded ASAP, taking priority of any in progress.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants