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
#include <softadastra/sdk.hpp>Basic usage
ClientOptions is passed to Client when creating a client.
#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;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Node id
Every client needs a local logical node id.
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.
ClientOptions options{""};
if (!options.is_valid())
{
// Invalid: node id is empty.
}2
3
4
5
6
Recommended mode
For real applications, use persistent mode.
auto options = softadastra::sdk::ClientOptions::persistent(
"my-app",
"data/my-app.wal"
);2
3
4
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.
auto options = softadastra::sdk::ClientOptions::local("node-1");local() is an alias for memory_only().
auto options = softadastra::sdk::ClientOptions::memory_only("node-1");Local mode:
does not use a WAL file
does not persist data across restart
keeps data in memory only
is useful for tests and simple examples2
3
4
Persistent mode
Use persistent mode when local data must survive restarts.
auto options = softadastra::sdk::ClientOptions::persistent(
"node-1",
"data/sdk-store.wal"
);2
3
4
Persistent mode:
enables the local store WAL
enables automatic flushing
uses sync_batch_size = 64
uses max_sync_retries = 5
requires acknowledgements
automatically queues local operations2
3
4
5
6
durable() is an explicit alias for persistent().
auto options = softadastra::sdk::ClientOptions::durable(
"node-1",
"data/sdk-store.wal"
);2
3
4
Fast mode
Use fast mode for benchmarks or controlled environments.
auto options = softadastra::sdk::ClientOptions::fast(
"node-1",
"data/sdk-store.wal"
);2
3
4
Fast mode keeps WAL persistence enabled, but disables automatic flushing after every write.
Fast mode:
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 operations2
3
4
5
6
Use this mode only when throughput matters more than maximum write durability.
Configuration modes
| Mode | WAL | Auto flush | Batch size | Retries | Require ack | Best for |
|---|---|---|---|---|---|---|
local() | no | no | 64 | 2 | no | tests |
memory_only() | no | no | 64 | 2 | no | tests |
persistent() | yes | yes | 64 | 5 | yes | applications |
durable() | yes | yes | 64 | 5 | yes | applications |
fast() | yes | no | 128 | 2 | no | benchmarks |
WAL path
The WAL path defines where persistent local data is stored.
auto options = softadastra::sdk::ClientOptions::persistent(
"node-1",
"data/app.wal"
);2
3
4
Create the parent directory before running the application:
mkdir -p dataIf WAL persistence is enabled, the WAL path must not be empty.
auto options = softadastra::sdk::ClientOptions::persistent(
"node-1",
""
);
if (!options.is_valid())
{
// Invalid: WAL path is empty while WAL is enabled.
}2
3
4
5
6
7
8
9
Manual setters
You can build options manually.
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);2
3
4
5
6
7
8
9
10
11
12
13
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.
options.set_initial_store_capacity(2048);The value must be greater than zero.
options.set_initial_store_capacity(0);
if (!options.is_valid())
{
// Invalid: initial store capacity cannot be zero.
}2
3
4
5
6
Sync batch size
The sync batch size controls the maximum number of operations produced in one sync batch.
options.set_sync_batch_size(128);The value must be greater than zero.
options.set_sync_batch_size(0);
if (!options.is_valid())
{
// Invalid: sync batch size cannot be zero.
}2
3
4
5
6
Sync retries
The maximum sync retry count controls how many times expired operations can be retried.
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.
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.
options.set_auto_queue(true);Most applications should keep this enabled.
Enable transport
Transport is optional.
Use with_local_transport() for localhost development:
ClientOptions options = ClientOptions::memory_only("node-1").with_local_transport(9100);This enables transport with host:
127.0.0.1and port:
9100You can also provide an explicit host:
ClientOptions options = ClientOptions::memory_only("node-1").with_transport("0.0.0.0", 9100);After enabling transport, the client can start it:
Client client{options};
client.open();
client.start_transport();2
3
4
Disable transport
options.disable_transport();Disabling transport resets the transport host to:
0.0.0.0and the port to:
0Enable discovery
Discovery is optional.
Use with_local_discovery() for localhost development:
ClientOptions options = ClientOptions::memory_only("node-1").with_local_discovery(5051);You can also provide an explicit host:
ClientOptions options = ClientOptions::memory_only("node-1").with_discovery("0.0.0.0", 5051);After enabling discovery, the client can start it:
Client client{options};
client.open();
client.start_discovery();2
3
4
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:
ClientOptions options = ClientOptions::memory_only("node-1").with_local_discovery(5051);Disable discovery
options.disable_discovery();Disabling discovery resets the discovery host to:
0.0.0.0and the port to:
0Metadata
Metadata identifies the local node with a human-readable name and version.
ClientOptions options = ClientOptions::memory_only("node-1").with_metadata("My Local Node", "0.1.0");You can also set metadata manually:
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.
if (!options.is_valid())
{
return 1;
}2
3
4
valid() is also available as a backward-compatible alias.
if (!options.valid())
{
return 1;
}2
3
4
Validation rules
ClientOptions is valid only when:
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 empty2
3
4
5
6
7
Complete persistent example
#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;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Complete transport example
#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;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Complete discovery example
#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;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Summary
Use:
ClientOptions::persistent("node-1", "data/app.wal")for real applications.
Use:
ClientOptions::local("node-1")for tests and examples.
Use:
ClientOptions::fast("node-1", "data/app.wal")for benchmarks or controlled environments.
Next, continue with Results and Errors.