Vix.cpp docs moved to vixcpp.com
Skip to content

Client Options ​

softadastra::sdk::ClientOptions configures how a Softadastra C++ SDK client is initialized.

It controls the local node id, persistence mode, WAL path, sync behavior, optional transport, optional discovery, and node metadata.

Include ​

cpp
#include <softadastra/sdk.hpp>

Basic usage ​

ClientOptions is passed to Client when creating a client.

cpp
#include <softadastra/sdk.hpp>

int main()
{
    using namespace softadastra::sdk;

    ClientOptions options =
        ClientOptions::persistent(
            "my-app",
            "data/my-app.wal"
        );

    Client client{options};
    const auto opened = client.open();

    if (opened.is_err())
    {
        return 1;
    }

    client.close();
    return 0;
}

Node id ​

Every client needs a local logical node id.

cpp
ClientOptions options{"node-1"};

The node id identifies the local SDK node inside the sync, metadata, transport, and discovery layers.

A valid node id must not be empty.

cpp
ClientOptions options{""};

if (!options.is_valid())
{
    // Invalid: node id is empty.
}

For real applications, use persistent mode.

cpp
auto options = softadastra::sdk::ClientOptions::persistent(
    "my-app",
    "data/my-app.wal"
);

Persistent mode enables WAL-backed local storage and automatic flushing after local writes.

This is the best default because it gives the application restart recovery.

Local mode ​

Use local mode for quick tests and examples.

cpp
auto options = softadastra::sdk::ClientOptions::local("node-1");

local() is an alias for memory_only().

cpp
auto options = softadastra::sdk::ClientOptions::memory_only("node-1");

Local mode:

txt
does not use a WAL file
does not persist data across restart
keeps data in memory only
is useful for tests and simple examples

Persistent mode ​

Use persistent mode when local data must survive restarts.

cpp
auto options = softadastra::sdk::ClientOptions::persistent(
    "node-1",
    "data/sdk-store.wal"
);

Persistent mode:

txt
enables the local store WAL
enables automatic flushing
uses sync_batch_size = 64
uses max_sync_retries = 5
requires acknowledgements
automatically queues local operations

durable() is an explicit alias for persistent().

cpp
auto options = softadastra::sdk::ClientOptions::durable(
    "node-1",
    "data/sdk-store.wal"
);

Fast mode ​

Use fast mode for benchmarks or controlled environments.

cpp
auto options = softadastra::sdk::ClientOptions::fast(
    "node-1",
    "data/sdk-store.wal"
);

Fast mode keeps WAL persistence enabled, but disables automatic flushing after every write.

Fast mode:

txt
enables the local store WAL
disables automatic flushing
uses sync_batch_size = 128
uses max_sync_retries = 2
does not require acknowledgements
automatically queues local operations

Use this mode only when throughput matters more than maximum write durability.

Configuration modes ​

ModeWALAuto flushBatch sizeRetriesRequire ackBest for
local()nono642notests
memory_only()nono642notests
persistent()yesyes645yesapplications
durable()yesyes645yesapplications
fast()yesno1282nobenchmarks

WAL path ​

The WAL path defines where persistent local data is stored.

cpp
auto options = softadastra::sdk::ClientOptions::persistent(
    "node-1",
    "data/app.wal"
);

Create the parent directory before running the application:

bash
mkdir -p data

If WAL persistence is enabled, the WAL path must not be empty.

cpp
auto options = softadastra::sdk::ClientOptions::persistent(
    "node-1",
    ""
);

if (!options.is_valid())
{
    // Invalid: WAL path is empty while WAL is enabled.
}

Manual setters ​

You can build options manually.

cpp
using namespace softadastra::sdk;

ClientOptions options{"node-1"};

options.set_store_wal_path("data/app.wal");
options.set_store_wal_enabled(true);
options.set_auto_flush(true);
options.set_initial_store_capacity(1024);

options.set_sync_batch_size(64);
options.set_max_sync_retries(5);
options.set_require_ack(true);
options.set_auto_queue(true);

For most applications, prefer persistent() instead of configuring every field manually.

Initial store capacity ​

The initial store capacity is a capacity hint for the local store.

cpp
options.set_initial_store_capacity(2048);

The value must be greater than zero.

cpp
options.set_initial_store_capacity(0);

if (!options.is_valid())
{
    // Invalid: initial store capacity cannot be zero.
}

Sync batch size ​

The sync batch size controls the maximum number of operations produced in one sync batch.

cpp
options.set_sync_batch_size(128);

The value must be greater than zero.

cpp
options.set_sync_batch_size(0);

if (!options.is_valid())
{
    // Invalid: sync batch size cannot be zero.
}

Sync retries ​

The maximum sync retry count controls how many times expired operations can be retried.

cpp
options.set_max_sync_retries(5);

Use a higher retry count for applications that need stronger delivery attempts.

Use a lower retry count for tests or controlled environments.

Acknowledgements ​

require_ack() controls whether outbound operations require acknowledgements.

cpp
options.set_require_ack(true);

Persistent mode enables acknowledgements by default.

Fast mode disables acknowledgements by default.

Auto queue ​

auto_queue() controls whether local operations are automatically queued for synchronization.

cpp
options.set_auto_queue(true);

Most applications should keep this enabled.

Enable transport ​

Transport is optional.

Use with_local_transport() for localhost development:

cpp
ClientOptions options = ClientOptions::memory_only("node-1").with_local_transport(9100);

This enables transport with host:

txt
127.0.0.1

and port:

txt
9100

You can also provide an explicit host:

cpp
ClientOptions options = ClientOptions::memory_only("node-1").with_transport("0.0.0.0", 9100);

After enabling transport, the client can start it:

cpp
Client client{options};

client.open();
client.start_transport();

Disable transport ​

cpp
options.disable_transport();

Disabling transport resets the transport host to:

txt
0.0.0.0

and the port to:

txt
0

Enable discovery ​

Discovery is optional.

Use with_local_discovery() for localhost development:

cpp
ClientOptions options = ClientOptions::memory_only("node-1").with_local_discovery(5051);

You can also provide an explicit host:

cpp
ClientOptions options = ClientOptions::memory_only("node-1").with_discovery("0.0.0.0", 5051);

After enabling discovery, the client can start it:

cpp
Client client{options};

client.open();
client.start_discovery();

Discovery and transport ​

Discovery needs the transport runtime internally.

If discovery is enabled, the SDK builds the transport layer internally so discovered peers can be represented as connectable nodes.

For normal use, you only need:

cpp
ClientOptions options = ClientOptions::memory_only("node-1").with_local_discovery(5051);

Disable discovery ​

cpp
options.disable_discovery();

Disabling discovery resets the discovery host to:

txt
0.0.0.0

and the port to:

txt
0

Metadata ​

Metadata identifies the local node with a human-readable name and version.

cpp
ClientOptions options = ClientOptions::memory_only("node-1").with_metadata("My Local Node", "0.1.0");

You can also set metadata manually:

cpp
options.set_metadata("My Local Node", "0.1.0");

If the display name is empty, the SDK can use the node id as the display label.

Validate options ​

Use is_valid() before opening a client if you build options manually.

cpp
if (!options.is_valid())
{
    return 1;
}

valid() is also available as a backward-compatible alias.

cpp
if (!options.valid())
{
    return 1;
}

Validation rules ​

ClientOptions is valid only when:

txt
node_id is not empty
WAL path is not empty when WAL is enabled
initial store capacity is greater than zero
sync batch size is greater than zero
transport host and port are valid when transport is enabled
discovery host and port are valid when discovery is enabled
version is not empty

Complete persistent example ​

cpp
#include <softadastra/sdk.hpp>
#include <iostream>

int main()
{
    using namespace softadastra::sdk;

    ClientOptions options = ClientOptions::persistent(
            "persistent-node",
            "data/persistent-node.wal"
        ).with_metadata(
            "Persistent Node",
            "0.1.0"
        );

    if (!options.is_valid())
    {
        std::cerr << "invalid client options\n";
        return 1;
    }

    Client client{options};
    const auto opened = client.open();

    if (opened.is_err())
    {
        std::cerr << opened.error().code_string() << ": "
                  << opened.error().message() << "\n";
        return 1;
    }

    const auto saved = client.put("profile/name", "Ada");

    if (saved.is_err())
    {
        std::cerr << saved.error().code_string() << ": "
                  << saved.error().message() << "\n";
        client.close();
        return 1;
    }

    client.close();
    return 0;
}

Complete transport example ​

cpp
#include <softadastra/sdk.hpp>
#include <iostream>

int main()
{
    using namespace softadastra::sdk;

    ClientOptions options = ClientOptions::memory_only("transport-node")
                              .with_local_transport(9100)
                              .with_metadata("Transport Node", "0.1.0");
    Client client{options};
    const auto opened = client.open();

    if (opened.is_err())
    {
        std::cerr << opened.error().message() << "\n";
        return 1;
    }

    const auto started = client.start_transport();

    if (started.is_err())
    {
        std::cerr << started.error().message() << "\n";
        client.close();
        return 1;
    }

    std::cout << "transport running: " << (client.transport_running() ? "yes" : "no") << "\n";

    client.stop_transport();
    client.close();

    return 0;
}

Complete discovery example ​

cpp
#include <softadastra/sdk.hpp>
#include <iostream>

int main()
{
    using namespace softadastra::sdk;

    ClientOptions options = ClientOptions::memory_only("discovery-node")
                                .with_local_discovery(5051)
                                .with_metadata("Discovery Node", "0.1.0");
    Client client{options};
    const auto opened = client.open();

    if (opened.is_err())
    {
        std::cerr << opened.error().message() << "\n";
        return 1;
    }

    const auto started = client.start_discovery();

    if (started.is_err())
    {
        std::cerr << started.error().message() << "\n";
        client.close();
        return 1;
    }

    std::cout << "discovery running: " << (client.discovery_running() ? "yes" : "no") << "\n";

    client.stop_discovery();
    client.close();

    return 0;
}

Summary ​

Use:

cpp
ClientOptions::persistent("node-1", "data/app.wal")

for real applications.

Use:

cpp
ClientOptions::local("node-1")

for tests and examples.

Use:

cpp
ClientOptions::fast("node-1", "data/app.wal")

for benchmarks or controlled environments.

Next, continue with Results and Errors.

Released under the Apache License 2.0.