Flag update flow

This section describes how the changes in the CloudBees Feature Flags dashboard affects flag values on the end device (mobile, web, backend) and how these changes can be controlled by the developer.

Stateless architecture

CloudBees Feature Flags uses a stateless architecture by default, which means that each SDK pulls a static JSON file from CloudBees Feature Flags cloud storage.

The CloudBees Feature Flags stateless architecture has a few key advantages:

  • Scale - Does not matter if you have hundreds of users or millions of users, the SDK fetches a static file.

  • Speed - No computation is done on the CloudBees Feature Flags servers. All flag computation is done in memory on the target platform.

  • Resiliency - CloudBees Feature Flags servers are NOT in the critical path of your software. If CloudBees Feature Flags is down for some reason, you will simply be unable to make flag changes via the dashboard but there will be no effect to your application. Also, the SDKs have a caching mechanism. In the case of a network issue, the effects are minimal as well.

  • Privacy - CloudBees Feature Flags does not send or know any of your user private data, everything happens on the target application.

  • Global Usage - CloudBees Feature Flags leverages the power of Amazon CloudFront for its Content Delivery Network. The deliberate inclusion of CloudFront in our architecture provides a unique advantage over other technologies' CDN systems that report outages and difficulties in certain geographic areas. In short, this part of the CloudBees Feature Flags infrastructure alleviates developers from creating proxies or requiring bootstrapping that would otherwise be necessary to maintain a connection in problematic regions.

Note - CloudBees Feature Flags uses Server Sent Event (SSE) to push to the SDKs a message to download a new JSON config file on config change, so changes are propagated to the clients instantly upon modification.

Client side SDK update flow

SDK setup flow

The client SDK setup flow operates in the following sequence:

  1. Synchronous local storage fetching:

    • The application calls the Rox SDK setup function

    • The SDK checks for existing configuration in local storage

    • The configuration is applied synchronously

    • Setup function returns with all configured Experiments applied on the device

  2. Asynchronous network fetching

    • In Parallel to the local storage flow, an asynchronous network request is called from the SDK to the CloudBees Feature Flags Storage services

    • When the network request is returned:

      • Configuration is applied

      • Configuration is saved on local storage

Client side update flow

SDK foreground configuration fetching flow

On relevant clients (mobile, TV, etc.) when the SDK identifies a foreground event, it triggers an asynchronous configuration fetching sequence to get a new configuration (if one exists) on CloudBees Feature Flags servers.

Configuration fetching

Flag freeze

See Understanding a flag freeze for information on when and how to freeze and unfreeze flags.

Server side SDK update flow

  • Server-side SDKs fetch a new configuration file periodically. The various settings for each SDK are listed below:

SDK Default (in seconds) Minimum (in seconds)

JVM

60

30

.NET

60

30

Node.js

60

30

JS SSR

60

30

Python

60

30

Go

60

30 (see additional notes)

PHP

30

30 (see additional notes)

C

60

30 (see additional notes)

C++

60

30 (see additional notes)

  • To change the default time frame, use FetchInterval / fetchIntervalInSec at the RoxOptions object, example:

JVM .NET Node.js Python Go PHP C C++
RoxOptions options = new RoxOptions.Builder()
  .withFetchIntervalInSeconds(50)
  .withVersion("1.2.0")
  .build();
Rox.setup(this, options);
RoxOptions options = new RoxOptions(new RoxOptions.RoxOptionsBuilder{
    Version = "1.0.4",
    FetchInterval = 60
});
await Rox.Setup(appKey, options);
Rox.register('', container);
const options = {
  version: '2.0.0',
  fetchIntervalInSec: 60
};
Rox.setup(ROLLOUT_KEY, options);
from rox.server.rox import Rox
from rox.server.rox_options import RoxOptions

# setup configuration_fetched_handler in the options object
options = RoxOptions(
    version="1.3.1"
    fetch_interval=60
)
cancel_event = Rox.setup('<key>', options).result();
import (
  "time"
  "github.com/rollout/rox-go/server"
  "github.com/rollout/rox-go/core/model"
)

var rox *server.Rox

func setupRollout() {
  options := server.NewRoxOptions(server.RoxOptionsBuilder{
    Version: "2.0.0",
    FetchInterval: time.Minute })
  rox = server.NewRox()
}
use Rox\Server\Rox;
use Rox\Server\RoxOptions;
use Rox\Server\RoxOptionsBuilder;

$roxOptionsBuilder = (new RoxOptionsBuilder())
    ->setVersion("2.0.0")
  ->setConfigFetchIntervalInSeconds(60);

Rox::setup(ROLLOUT_KEY, new RoxOptions($roxOptionsBuilder));
#include <rollout.h>

RoxOptions *options = rox_options_create();
rox_options_set_fetch_interval(options, 60);
rox_setup(DEFAULT_API_KEY, options);
#include <rollout.hpp>

Rox::Options *options = Rox::OptionsBuilder()
  .SetFetchInterval(60)
    .Build();

Rox::Setup(DEFAULT_API_KEY, options);
  • Additonal notes

    • Go - The option parameter tye is time.duration is in nano-seconds.

    • C/C++ - There is an additional 0 option permitted to indicate that the fetch will not be periodic.

    • PHP - PHP is different from other server side SDKs as it’s not a live server, but a cache on the storage with a strategy that expires every 30 seconds. We use Kevinrob\GuzzleCache\CacheMiddleware with a strategy.

Configuration fetched handler

See Configuration fetched handler for information on how to identify when the SDKs have loaded the configuration from the local storage or network.