Page MenuHomePhabricator

[GrowthBook Integration] Implement GrowthBook experiment polling client
Open, HighPublic5 Estimated Story Points

Description

Description

Build a backend client that periodically fetches experiment configurations from the GrowthBook API.

The client should support configurable polling intervals, handle timeouts and retries, and log failures without affecting API availability.
The fetched data should be made available to the experiment configuration service for processing.

Technical Notes

Relevant files:

  • config/configuration.js - owns service config and axios defaults, so GrowthBook URL, polling interval, token/secret, and timeout config live here
  • app.js - startup/wiring point so where the poller should be initialized
  • service/serviceRegistry.js - register the new services

New files:

  • service/growthBookClient.js
    • data access layer
    • how to talk to GrowthBook to fetch data
    • a thin, reusable client for making requests to the GrowthBook API
    • responsibilities:
      • know the endpoint URLs
      • handle HTTP requests
      • apply auth headers
      • handle timeouts / retries (lightweight)
      • return raw (or lightly parsed) data
    • use by growthBookPoller
  • service/growthBookPoller.js
    • orchestration layer
    • when and how often to fetch from GrowthBook and what to do with the results
    • a background process that periodically fetches data using the client and updates the service’s current state
    • responsibilities:
      • run on an interval
      • call growthBookClient.fetchExperiments()
      • handle failures gracefully
      • maintain latest successful result
      • trigger downstream processing (validate > adapt > stitch > store)
    • initialized in app.js
    • calls into experimentConfigurationService.js on update

Why separation?

  • clean unit tests:
    • test client with mocked HTTP
    • test poller with mocked client
  • flexible reuse of the client

How these 2 should work together:

  • GrowthBookPoller calls GrowthBookClient
  • GrowthBookClient returns raw experiments
  • experiments handed to configuration service
  • experiments go thru funnel:
    • validate
    • adapt
    • stitch
    • store
  • API serves result

How should failure be handled?

  • If we have not had a successful request from GB, we should not invalidate the local cache. We would want Varnish to preserve its cache until we get a valid update from GB.

Data retrieved from GB should be stored in the TK database as well as in memory. (Note: if there's a reason that storing in the database expands the scope, this requirement can be changed.)

Pseudo Code
class GrowthBookClient {
  constructor( { baseUrl, apiKey, timeout } ) {
    this.baseUrl = baseUrl;
    this.apiKey = apiKey;
    this.timeout = timeout;
  }

  async fetchExperiments() {
    const response = await axios.get(
      `${this.baseUrl}/experiments`,
      {
        headers: { Authorization: `Bearer ${this.apiKey}` },
        timeout: this.timeout
      }
    );

    return response.data;
  }
}

// ...

class GrowthBookPoller {
  constructor( {
    client,
    intervalMs,
    onUpdate,
    logger
  } ) {
    this.client = client;
    this.intervalMs = intervalMs;
    this.onUpdate = onUpdate;
    this.logger = logger;
    this.timer = null;
  }

  start() {
    this.run();
    this.timer = setInterval( () => this.run(), this.intervalMs );
  }

  async run() {
    try {
      const data = await this.client.fetchExperiments();
      this.onUpdate( data ); // hand off to config service
      this.logger.info( 'GrowthBook poll succeeded' );
    } catch ( e ) {
      this.logger.error( 'GrowthBook poll failed', e );
    }
  }
}

Acceptance Criteria

  • Backend can fetch experiment configs from the configured GrowthBook API endpoint.
  • Poll interval, timeout, and retry settings are configurable. Default polling interval should start at 1minute.
  • Poll failures are logged and do not crash the service.
  • Poller can be started from app initialization and cleanly skipped/disabled via config.
  • Unit tests cover successful fetch, timeout/failure behavior, and malformed upstream response handling.
  • Documentation?

Event Timeline

KReid-WMF moved this task from Incoming to READY TO GROOM on the Test Kitchen board.
KReid-WMF set the point value for this task to 5.
KReid-WMF moved this task from READY TO GROOM to Backlog on the Test Kitchen board.

brouberol merged https://gitlab.wikimedia.org/repos/data-engineering/growthbook/-/merge_requests/45

New docker image for staging that includes status as a filter in the API

Change #1288237 had a related patch set uploaded (by Santiago Faci; author: Santiago Faci):

[operations/deployment-charts@master] growtbook-next: New release that supports status as a filter for API

https://gerrit.wikimedia.org/r/1288237

Change #1288237 merged by jenkins-bot:

[operations/deployment-charts@master] growtbook-next: New release that supports status as a filter for API

https://gerrit.wikimedia.org/r/1288237

Change #1289366 had a related patch set uploaded (by Santiago Faci; author: Santiago Faci):

[operations/deployment-charts@master] growtbook: New release that supports status as a filter for API

https://gerrit.wikimedia.org/r/1289366

Change #1289366 merged by jenkins-bot:

[operations/deployment-charts@master] growtbook: New release that supports status as a filter for API

https://gerrit.wikimedia.org/r/1289366

sfaci merged https://gitlab.wikimedia.org/repos/data-engineering/test-kitchen/-/merge_requests/329

Implement GrowthBook validator, adapter, and reconstructed experiment API endpoints

Change #1295092 had a related patch set uploaded (by Santiago Faci; author: Santiago Faci):

[operations/deployment-charts@master] test-kitchen: Update chart to add a new config property

https://gerrit.wikimedia.org/r/1295092

Change #1295094 had a related patch set uploaded (by Santiago Faci; author: Santiago Faci):

[operations/deployment-charts@master] Test Kitchen UI: Deploy v1.3.8 release to staging

https://gerrit.wikimedia.org/r/1295094

Change #1295092 merged by jenkins-bot:

[operations/deployment-charts@master] test-kitchen: Update chart to add a new config property

https://gerrit.wikimedia.org/r/1295092

Change #1295094 merged by jenkins-bot:

[operations/deployment-charts@master] Test Kitchen UI: Deploy v1.3.8 release to staging

https://gerrit.wikimedia.org/r/1295094

Change #1296660 had a related patch set uploaded (by Santiago Faci; author: Santiago Faci):

[operations/deployment-charts@master] Test Kitchen UI: Deploy v1.3.9 release to production

https://gerrit.wikimedia.org/r/1296660

Change #1296660 merged by jenkins-bot:

[operations/deployment-charts@master] Test Kitchen UI: Deploy v1.3.9 release to production

https://gerrit.wikimedia.org/r/1296660