Skip to content

Firebolt CPP 2.0 Client

Sathishkumar edited this page Aug 14, 2026 · 1 revision

Firebolt Client

Overview

FireboltClient introduces an explicit runtime context that binds Firebolt Models and Transport implementations together.

Unlike the existing singleton-based architecture, Firebolt CPP 2.0 applications explicitly create and own a FireboltClient instance.

The client is responsible for:

  • Accessing generated Firebolt APIs
  • Managing request execution
  • Managing response callbacks
  • Managing event subscriptions
  • JSON-RPC request correlation
  • Dispatching responses and notifications
  • Bridging strongly typed Firebolt Models with the underlying Transport

The client is intentionally independent of any specific transport implementation and operates exclusively through the IFireboltTransport abstraction.


Design Goals

  • Explicit ownership
  • Eliminate global singleton dependencies
  • Support multiple FireboltClient instances
  • Transport abstraction
  • Strongly typed APIs
  • Callback-based asynchronous execution
  • Simplified request lifecycle management

Firebolt Client Architecture

+----------------------+
| Generated APIs       |
| Lifecycle            |
| Discovery            |
| Device               |
| Advertising          |
+----------+-----------+
           |
           v

+----------------------+
|    FireboltClient    |
+----------------------+
| send<T>()            |
| subscribe<T>()       |
| cancel()             |
| unsubscribe()        |
| Response Callbacks   |
| Event Callbacks      |
| JSON-RPC Correlation |
+----------+-----------+
           |
           v

+----------------------+
| IFireboltTransport   |
+----------+-----------+
           |
           v

+----------------------+
| Transport Impl       |
+----------------------+

The Firebolt Client serves as the runtime execution layer between generated APIs and transport implementations.


Why FireboltClient?

The current architecture relies on a globally shared singleton instance.

Application
      |
      v
firebolt::Instance()
      |
      v
Generated APIs
      |
      v
Transport

This limits flexibility by coupling all generated APIs to a single runtime transport context.

Firebolt CPP 2.0 introduces explicit ownership:

Application
      |
      v
FireboltClient
      |
      +-- Lifecycle
      +-- Discovery
      +-- Device
      +-- Advertising
      |
      v
IFireboltTransport

Applications control:

  • Client lifetime
  • Transport selection
  • Interface access

Responsibilities

Request Execution

The client is responsible for executing generated Firebolt API requests.

For every request:

  1. Generate a JSON-RPC request identifier.
  2. Register a callback.
  3. Dispatch the request through IFireboltTransport.
  4. Correlate the response.
  5. Execute the callback.
  6. Remove callback state.

Response Correlation

Responses are matched using JSON-RPC identifiers.

Request Id
      │
      ▼

Response Callback Map
      │
      ▼

Typed Callback Execution

The client owns all correlation state.


Event Processing

The client also manages long-lived event subscriptions.

Event Name
      │
      ▼
Event Callback Map
      │
      ▼
Application Callback

Unlike response callbacks, event callbacks remain registered until explicitly removed.


Cancellation

The client supports request and subscription cancellation.

client.cancel(handle);

client.unsubscribe(eventHandle);

Cancellation behavior is implemented within the client and remains independent of the underlying transport implementation.


Request Lifecycle

Generated API
      │
      ▼

Firebolt Model
      │
      ▼

FireboltClient
      │
      ├─ Generate Request Id
      ├─ Register Callback
      └─ Dispatch Request

      │
      ▼

IFireboltTransport
      │
      ▼

Firebolt Runtime

      │
      ▼

Response Received
      │
      ▼

Correlation Lookup
      │
      ▼

Typed Callback Execution

The client remains responsible for all callback registration and response correlation.


Interface Access

Generated Firebolt APIs are instantiated using a specific FireboltClient instance.

FireboltClient firebolt(transport);

#include "firebolt/lifecycle.h"

Lifecycle lifecycle(firebolt);

This removes the dependency on a globally shared singleton while making the runtime execution context explicit.

This approach keeps generated interfaces lightweight while allowing FireboltClient to remain solely responsible for request execution, callback routing, and transport communication.


Benefits

Explicit Ownership

Applications own the client and transport lifecycle.

Transport Independence

The client depends only on IFireboltTransport.

Improved Testability

Mock and test transport implementations can be injected.

Simplified Runtime Model

Generated APIs no longer rely on globally shared state.

Strong Typing

Firebolt Models remain strongly typed throughout request execution.

Separation of Concerns

Models define data.

Transport moves messages.

FireboltClient executes requests and events.


Key Takeaway

The Firebolt Client serves as the runtime execution layer of Firebolt CPP 2.0.

It binds:

  • Firebolt Models
  • Generated APIs
  • Transport Implementations

into a single execution context while maintaining strong typing, explicit ownership, and transport independence.