Skip to content

[FSSDK-11172] feat: update decision service to handle CMAB #602

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

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

muzahidul-opti
Copy link
Contributor

Summary

  • Update decision service to handle CMAB
  • Add async support for decide apis
  • Refractor default bucketer to handle CMAB traffic allocation

Test plan

Issues

  • FSSDK-11172

@muzahidul-opti muzahidul-opti marked this pull request as ready for review July 2, 2025 12:05
@muzahidul-opti muzahidul-opti requested a review from raju-opti July 2, 2025 12:06
# Conflicts:
#	Sources/CMAB/CmabService.swift
#	Tests/OptimizelyTests-Common/CmabServiceTests.swift
Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

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

It looks good. I have a suggestion to clean up .opType passing down.
Let's discuss about the option.


extension DefaultCmabService {
static func createDefault() -> DefaultCmabService {
let DEFAULT_CMAB_CACHE_TIMEOUT = 30 * 60 * 1000 // 30 minutes in milliseconds
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this timeout is too large - is this consistent for all SDKs? @raju-opti

Comment on lines +48 to 52
if !mutexAllowed {
return DecisionResponse(result: nil, reasons: reasons)
}

if !mutexAllowed { return DecisionResponse(result: nil, reasons: reasons) }
Copy link
Contributor

Choose a reason for hiding this comment

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

clean up redundant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, reuse the mutex logic.


var cmabDecision: CmabDecision?
/// Fetch CMAB decision
let response = cmabService.getDecision(config: config, userContext: user, ruleId: experiment.id, options: options ?? [])
Copy link
Contributor

Choose a reason for hiding this comment

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

This is blocking call. Is it ok?

return
}

let decision = self.decide(user: user, keys: config.featureFlagKeys, options: options, opType: .async, ignoreDefaultOptions: false)
Copy link
Contributor

Choose a reason for hiding this comment

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

why "ignoreDefaultOptions=false" here? Not consistent with sync version above?

Comment on lines +98 to +103
guard opType == .async else {
let info = LogMessage.cmabNotSupportedInSyncMode
logger.w(info)
reasons.addInfo(info)
return DecisionResponse(result: nil, reasons: reasons)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we check if running thread, and reject if main thread?
CMAB can be called in sync decide inside of background thread?

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.

2 participants