Skip to content

[FSSDK-11149] Ruby: Implement CMAB Client #364

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

Merged
merged 7 commits into from
Jun 13, 2025

Conversation

esrakartalOpt
Copy link
Contributor

Summary

  • Implement CMAB client
  • Added new test cases

Test plan

Created new unit test cases

Issues

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request implements a new CMAB client in Ruby along with unit tests to ensure correct behavior for various response scenarios. Key changes include:

  • Implementation of the CMAB client with retry logic and HTTP error handling.
  • Addition of new unit tests to confirm client behavior under normal and error conditions.
  • Introduction of custom constants and exception classes for CMAB error management.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
spec/cmab_client_spec.rb Provides comprehensive tests for CMAB client functionality
lib/optimizely/helpers/constants.rb Adds CMAB-specific constants for error messages
lib/optimizely/exceptions.rb Introduces custom CMAB error exception classes
lib/optimizely/cmab/cmab_client.rb Implements the CMAB client with request, retry, and response logic

# Contains parameters for maximum retries, backoff intervals, and multipliers.
attr_reader :max_retries, :initial_backoff, :max_backoff, :backoff_multiplier

def initialize(max_retries: DEFAULT_MAX_RETRIES, initial_backoff: DEFAULT_INITIAL_BACKOFF, max_backoff: DEFAULT_BACKOFF_MULTIPLIER, backoff_multiplier: DEFAULT_BACKOFF_MULTIPLIER)
Copy link
Preview

Copilot AI Jun 13, 2025

Choose a reason for hiding this comment

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

The default value for 'max_backoff' is incorrectly set to DEFAULT_BACKOFF_MULTIPLIER; it should likely reference DEFAULT_MAX_BACKOFF to correctly reflect the intended maximum backoff duration.

Suggested change
def initialize(max_retries: DEFAULT_MAX_RETRIES, initial_backoff: DEFAULT_INITIAL_BACKOFF, max_backoff: DEFAULT_BACKOFF_MULTIPLIER, backoff_multiplier: DEFAULT_BACKOFF_MULTIPLIER)
def initialize(max_retries: DEFAULT_MAX_RETRIES, initial_backoff: DEFAULT_INITIAL_BACKOFF, max_backoff: DEFAULT_MAX_BACKOFF, backoff_multiplier: DEFAULT_BACKOFF_MULTIPLIER)

Copilot uses AI. Check for mistakes.

Comment on lines 173 to 175
error_message = Optimizely::Helpers::Constants::CMAB_FETCH_FAILED % 'Exhausted all retries for CMAB request.'
@logger.log(Logger::ERROR, error_message)
raise Optimizely::CmabFetchError, error_message
Copy link
Preview

Copilot AI Jun 13, 2025

Choose a reason for hiding this comment

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

[nitpick] The error message and subsequent code after the retry loop appear unreachable since the loop already raises an error when max retries are exceeded; consider removing this redundant code.

Suggested change
error_message = Optimizely::Helpers::Constants::CMAB_FETCH_FAILED % 'Exhausted all retries for CMAB request.'
@logger.log(Logger::ERROR, error_message)
raise Optimizely::CmabFetchError, error_message
# Removed unreachable code after the retry loop.

Copilot uses AI. Check for mistakes.

Kernel.sleep(backoff)

backoff = [
backoff * (retry_config.backoff_multiplier**(attempt + 1)),

Choose a reason for hiding this comment

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

as we are using the previous backoff to get the new one, it should be

backoff = [
  backoff * retry_config.backoff_multiplier,
  retry_config.max_backoff
].min

expect(Kernel).not_to have_received(:sleep)
end

it 'should not return 200 status' do

Choose a reason for hiding this comment

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

maybe rename it to should raise error non non success status

expect(Kernel).not_to have_received(:sleep)
end

it 'should return invalid json' do

Choose a reason for hiding this comment

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

how about should raise error on invalid json response?

expect(Kernel).not_to have_received(:sleep)
end

it 'should return HTTP exception' do

Choose a reason for hiding this comment

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

how about should raise error on http client exception

expect(Kernel).not_to have_received(:sleep)
end

it 'should return invalid response structure' do

Choose a reason for hiding this comment

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

should raise error on invalid response structure

@esrakartalOpt esrakartalOpt merged commit 95f9e35 into master Jun 13, 2025
10 checks passed
@esrakartalOpt esrakartalOpt deleted the esra/FSSDK-11149_add_cmab_client branch June 13, 2025 20:01
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