Skip to content

Commit a6b15dd

Browse files
authored
[Feature] add config support (#26)
Signed-off-by: Haiyang Shi <[email protected]>
1 parent e52c4ee commit a6b15dd

File tree

8 files changed

+230
-52
lines changed

8 files changed

+230
-52
lines changed

client/transport/transport.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <sys/mman.h>
2828
#include <sys/time.h>
2929

30+
#include "priskv-config.h"
3031
#include "priskv-event.h"
3132
#include "priskv-log.h"
3233

@@ -59,18 +60,9 @@ static int priskv_build_check(void)
5960
static void __attribute__((constructor)) priskv_client_transport_init(void)
6061
{
6162
assert(!priskv_build_check());
63+
priskv_config_init();
6264

63-
const char *transport_env = getenv("PRISKV_TRANSPORT");
64-
priskv_transport_backend backend = PRISKV_TRANSPORT_BACKEND_RDMA;
65-
if (transport_env) {
66-
if (strcasecmp(transport_env, "UCX") == 0) {
67-
backend = PRISKV_TRANSPORT_BACKEND_UCX;
68-
} else if (strcasecmp(transport_env, "RDMA") == 0) {
69-
backend = PRISKV_TRANSPORT_BACKEND_RDMA;
70-
} else {
71-
priskv_log_error("Unknown transport backend: %s\n", transport_env);
72-
}
73-
}
65+
priskv_transport_backend backend = g_config.transport;
7466

7567
priskv_transport_driver *driver = NULL;
7668
switch (backend) {
@@ -96,10 +88,7 @@ static void __attribute__((constructor)) priskv_client_transport_init(void)
9688

9789
if (driver) {
9890
g_client_driver = driver;
99-
return 0;
10091
}
101-
102-
return -1;
10392
}
10493

10594
void priskv_keyset_free(priskv_keyset *keyset)

client/transport/transport.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,6 @@ extern "C"
3737
typedef struct priskv_conn_operation priskv_conn_operation;
3838
typedef struct priskv_transport_conn priskv_transport_conn;
3939

40-
typedef enum priskv_transport_backend {
41-
PRISKV_TRANSPORT_BACKEND_UCX,
42-
PRISKV_TRANSPORT_BACKEND_RDMA,
43-
PRISKV_TRANSPORT_BACKEND_MAX,
44-
} priskv_transport_backend;
45-
4640
typedef enum priskv_transport_mem_type {
4741
PRISKV_TRANSPORT_MEM_REQ,
4842
PRISKV_TRANSPORT_MEM_RESP,

cluster/client/client.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <time.h>
3434

3535
#include "client.h"
36+
#include "priskv-config.h"
3637
#include "priskv-log.h"
3738
#include "priskv-utils.h"
3839
#include "priskv-event.h"
@@ -41,11 +42,7 @@
4142
#include "crc16.h"
4243
#include "list.h"
4344

44-
#define PRISKV_META_DATA_KEY "priskv_cluster_metadata"
45-
#define PRISKV_META_SERVER_CONNECT_TIMEOUT_SECOND 5
4645
#define PRISKV_CLUSTER_SLOTS 4096
47-
#define PRISKV_DEFAULT_NQUEUE 0
48-
#define META_DATA_UPDATE_INTERVAL 5
4946

5047
typedef struct priskvClusterMetaServer priskvClusterMetaServer;
5148
typedef struct priskvClusterMetaData priskvClusterMetaData;
@@ -117,7 +114,7 @@ struct priskvClusterRequest {
117114
static int priskvClusterMetaServerConnect(priskvClusterMetaServer *metaServer, const char *addr,
118115
int port, const char *password)
119116
{
120-
struct timeval timeout = {PRISKV_META_SERVER_CONNECT_TIMEOUT_SECOND, 0};
117+
struct timeval timeout = {g_config.client.meta_server_connect_timeout_sec, 0};
121118

122119
metaServer->redisCtx = redisConnectWithTimeout(addr, port, timeout);
123120
if (!metaServer->redisCtx || metaServer->redisCtx->err) {
@@ -171,7 +168,7 @@ static priskvClusterMetaDataInfo *priskvClusterMetaDataGetFromServer(priskvClust
171168
priskvClusterMetaDataInfo *info = NULL;
172169
redisReply *reply;
173170

174-
reply = redisCommand(client->metaServer.redisCtx, "GET %s", PRISKV_META_DATA_KEY);
171+
reply = redisCommand(client->metaServer.redisCtx, "GET %s", g_config.client.metadata_key);
175172

176173
priskv_log_debug("priskvClusterMetaData: %s\n", reply->str);
177174

@@ -224,7 +221,7 @@ static inline int priskvClusterNodeOpen(priskvClusterClient *client, priskvClust
224221
node->id = id;
225222
node->addr = strdup(nodeInfo->addr);
226223
node->port = nodeInfo->port;
227-
node->client = priskv_connect(nodeInfo->addr, nodeInfo->port, NULL, 0, PRISKV_DEFAULT_NQUEUE);
224+
node->client = priskv_connect(nodeInfo->addr, nodeInfo->port, NULL, 0, g_config.client.nqueue);
228225
node->refCount = 0;
229226
if (!node->client) {
230227
priskv_log_error("Failed to connect to node %s:%d\n", nodeInfo->addr, nodeInfo->port);
@@ -596,8 +593,9 @@ static void priskvClusterTimerHandler(int fd, void *opaque, uint32_t events)
596593

597594
static int createMetaTimer(priskvClusterClient *client)
598595
{
599-
struct itimerspec its = {.it_interval = {.tv_sec = META_DATA_UPDATE_INTERVAL, .tv_nsec = 0},
600-
.it_value = {.tv_sec = META_DATA_UPDATE_INTERVAL, .tv_nsec = 0}};
596+
struct itimerspec its = {
597+
.it_interval = {.tv_sec = g_config.client.metadata_update_interval_sec, .tv_nsec = 0},
598+
.it_value = {.tv_sec = g_config.client.metadata_update_interval_sec, .tv_nsec = 0}};
601599

602600
int tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
603601
if (tfd < 0) {

include/priskv-config.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright (c) 2025 ByteDance Ltd. and/or its affiliates
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef __PRISKV_CONFIG__
16+
#define __PRISKV_CONFIG__
17+
18+
#if defined(__cplusplus)
19+
extern "C"
20+
{
21+
#endif
22+
23+
#include <ucs/config/parser.h>
24+
#include <ucs/config/types.h>
25+
#include <ucs/sys/compiler_def.h>
26+
#include <ucs/sys/preprocessor.h>
27+
28+
/**
29+
* @brief Declare config table.
30+
*
31+
* @param TABLE Config table.
32+
* @param NAME Name of config table.
33+
* @param PREFIX Prefix of config table.
34+
* @param TYPE Type of config table.
35+
*/
36+
#define PRISKV_CONFIG_DECLARE_TABLE(TABLE, NAME, PREFIX, TYPE) \
37+
static ucs_config_global_list_entry_t g_##TABLE##_config_entry = {.name = NAME, \
38+
.prefix = PREFIX, \
39+
.table = TABLE, \
40+
.size = sizeof(TYPE), \
41+
.list = {NULL, NULL}, \
42+
.flags = 0};
43+
44+
#define PRISKV_CONFIG_GET_TABLE(TABLE) &g_##TABLE##_config_entry
45+
#define PRISKV_ENV_PREFIX "PRISKV_"
46+
47+
/**
48+
* @brief Initialize config.
49+
*/
50+
void priskv_config_init(void);
51+
52+
/**
53+
* @brief Fill options from config entry.
54+
*
55+
* @param opts Options to fill.
56+
* @param entry Config entry.
57+
* @param env_prefix Prefix of environment variables.
58+
* @param ignore_errors Ignore errors if set to 1.
59+
* @return ucs_status_t UCS_OK on success, otherwise error.
60+
*/
61+
ucs_status_t priskv_config_parser_fill_opts(void *opts, ucs_config_global_list_entry_t *entry,
62+
const char *env_prefix, int ignore_errors);
63+
64+
/**
65+
* @brief Release options.
66+
*
67+
* @param opts Options to release.
68+
* @param fields Config fields.
69+
*/
70+
void priskv_config_parser_release_opts(void *opts, ucs_config_field_t *fields);
71+
72+
/**
73+
* @brief Set value for option.
74+
*
75+
* @param opts Options to set value.
76+
* @param fields Config fields.
77+
* @param prefix Prefix of option.
78+
* @param name Name of option.
79+
* @param value Value of option.
80+
* @return ucs_status_t UCS_OK on success, otherwise error.
81+
*/
82+
ucs_status_t priskv_config_parser_set_value(void *opts, ucs_config_field_t *fields,
83+
const char *prefix, const char *name,
84+
const char *value);
85+
86+
typedef enum priskv_transport_backend {
87+
PRISKV_TRANSPORT_BACKEND_RDMA,
88+
PRISKV_TRANSPORT_BACKEND_UCX,
89+
PRISKV_TRANSPORT_BACKEND_MAX,
90+
} priskv_transport_backend;
91+
92+
typedef struct priskv_client_config {
93+
int nqueue;
94+
int metadata_update_interval_sec;
95+
char *metadata_key;
96+
int meta_server_connect_timeout_sec;
97+
} priskv_client_config_t;
98+
99+
typedef struct priskv_server_config {
100+
101+
} priskv_server_config_t;
102+
103+
typedef struct priskv_config {
104+
priskv_transport_backend transport;
105+
priskv_client_config_t client;
106+
priskv_server_config_t server;
107+
} priskv_config_t;
108+
109+
extern priskv_config_t g_config;
110+
111+
#if defined(__cplusplus)
112+
}
113+
#endif
114+
115+
#endif /* __PRISKV_CONFIG__ */

lib/config.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright (c) 2025 ByteDance Ltd. and/or its affiliates
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "priskv-config.h"
16+
#include "priskv-log.h"
17+
#include <pthread.h>
18+
19+
static const char *priskv_transport_backend_names[] = {[PRISKV_TRANSPORT_BACKEND_RDMA] = "RDMA",
20+
[PRISKV_TRANSPORT_BACKEND_UCX] = "UCX",
21+
[PRISKV_TRANSPORT_BACKEND_MAX] = NULL};
22+
23+
static ucs_config_field_t priskv_client_config_table[] = {
24+
{"NQUEUE", "0", "Number of worker threads for client.",
25+
ucs_offsetof(priskv_client_config_t, nqueue),
26+
UCS_CONFIG_TYPE_INT},
27+
{"METADATA_KEY", "priskv_cluster_metadata", "Key to store cluster metadata.",
28+
ucs_offsetof(priskv_client_config_t, metadata_key),
29+
UCS_CONFIG_TYPE_STRING},
30+
{"METADATA_UPDATE_INTERVAL_SEC", "5", "Interval to update metadata in seconds.",
31+
ucs_offsetof(priskv_client_config_t, metadata_update_interval_sec),
32+
UCS_CONFIG_TYPE_INT},
33+
{"META_SERVER_CONNECT_TIMEOUT_SEC", "5", "Timeout to connect to meta server in seconds.",
34+
ucs_offsetof(priskv_client_config_t, meta_server_connect_timeout_sec),
35+
UCS_CONFIG_TYPE_INT},
36+
37+
{NULL}
38+
};
39+
40+
static ucs_config_field_t priskv_server_config_table[] = {
41+
{NULL}
42+
};
43+
44+
static ucs_config_field_t priskv_config_table[] = {
45+
{"TRANSPORT", "RDMA", "PrisKV Transport. Supported transports are [RDMA, UCX].",
46+
ucs_offsetof(priskv_config_t, transport),
47+
UCS_CONFIG_TYPE_ENUM(priskv_transport_backend_names)},
48+
49+
{"", "", NULL, ucs_offsetof(priskv_config_t, client),
50+
UCS_CONFIG_TYPE_TABLE(priskv_client_config_table)},
51+
52+
{"", "", NULL, ucs_offsetof(priskv_config_t, server),
53+
UCS_CONFIG_TYPE_TABLE(priskv_server_config_table)},
54+
55+
{NULL}
56+
};
57+
58+
PRISKV_CONFIG_DECLARE_TABLE(priskv_config_table, "PrisKV Config", NULL, priskv_config_t);
59+
60+
static pthread_once_t g_priskv_config_once = PTHREAD_ONCE_INIT;
61+
priskv_config_t g_config = {0};
62+
63+
static void priskv_config_init_impl(void)
64+
{
65+
ucs_status_t status = priskv_config_parser_fill_opts(
66+
&g_config, PRISKV_CONFIG_GET_TABLE(priskv_config_table), PRISKV_ENV_PREFIX, 1);
67+
if (status != UCS_OK) {
68+
priskv_log_error("Failed to initialize config: %s\n", ucs_status_string(status));
69+
} else {
70+
ucs_config_parser_print_opts(
71+
stdout, "PrisKV Environment Variables", &g_config, priskv_config_table, NULL,
72+
PRISKV_ENV_PREFIX,
73+
UCS_CONFIG_PRINT_CONFIG | UCS_CONFIG_PRINT_HEADER | UCS_CONFIG_PRINT_DOC, NULL);
74+
}
75+
}
76+
77+
void priskv_config_init(void)
78+
{
79+
pthread_once(&g_priskv_config_once, priskv_config_init_impl);
80+
}
81+
82+
ucs_status_t priskv_config_parser_fill_opts(void *opts, ucs_config_global_list_entry_t *entry,
83+
const char *env_prefix, int ignore_errors)
84+
{
85+
return ucs_config_parser_fill_opts(opts, entry, env_prefix, ignore_errors);
86+
}
87+
88+
void priskv_config_parser_release_opts(void *opts, ucs_config_field_t *fields)
89+
{
90+
ucs_config_parser_release_opts(opts, fields);
91+
}
92+
93+
ucs_status_t priskv_config_parser_set_value(void *opts, ucs_config_field_t *fields,
94+
const char *prefix, const char *name, const char *value)
95+
{
96+
97+
return ucs_config_parser_set_value(opts, fields, prefix, name, value);
98+
}

server/test/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ UCX_CFLAGS = $(shell pkg-config --cflags ucx)
4040
UCX_LIBS = $(shell pkg-config --libs ucx)
4141
ifeq ($(shell pkg-config --exists ucx; echo $$?),0)
4242
$(TEST_KV): $(OBJS)
43-
$(CC) test_kv.c ../../lib/workqueue.c ../../lib/threads.c ../../lib/event.c ../../lib/ucx.c ../memory.c ../kv.c ../slab.c ../buddy.c ../crc.c ../../lib/log.c ../backend/backend.c ../transport/transport.c ../transport/rdma.c ../transport/ucx.c ../tiering.c ../acl.c $(CFLAGS) $(UCX_CFLAGS) -o $(TEST_KV) -lmount -lrdmacm -libverbs $(UCX_LIBS)
43+
$(CC) test_kv.c ../../lib/workqueue.c ../../lib/threads.c ../../lib/event.c ../../lib/ucx.c ../../lib/config.c ../memory.c ../kv.c ../slab.c ../buddy.c ../crc.c ../../lib/log.c ../backend/backend.c ../transport/transport.c ../transport/rdma.c ../transport/ucx.c ../tiering.c ../acl.c $(CFLAGS) $(UCX_CFLAGS) -o $(TEST_KV) -lmount -lrdmacm -libverbs $(UCX_LIBS)
4444
else
4545
$(TEST_KV):
4646
@echo "UCX not available, skip $(TEST_KV)"
4747
endif
4848

4949
ifeq ($(shell pkg-config --exists ucx; echo $$?),0)
5050
$(TEST_KV_MT): $(OBJS)
51-
$(CC) test_kv_mt.c ../../lib/workqueue.c ../../lib/threads.c ../../lib/event.c ../../lib/ucx.c ../memory.c ../kv.c ../slab.c ../buddy.c ../crc.c ../../lib/log.c ../backend/backend.c ../transport/transport.c ../transport/rdma.c ../transport/ucx.c ../tiering.c ../acl.c $(CFLAGS) $(UCX_CFLAGS) -o $(TEST_KV_MT) -lmount -lrdmacm -libverbs $(UCX_LIBS)
51+
$(CC) test_kv_mt.c ../../lib/workqueue.c ../../lib/threads.c ../../lib/event.c ../../lib/ucx.c ../../lib/config.c ../memory.c ../kv.c ../slab.c ../buddy.c ../crc.c ../../lib/log.c ../backend/backend.c ../transport/transport.c ../transport/rdma.c ../transport/ucx.c ../tiering.c ../acl.c $(CFLAGS) $(UCX_CFLAGS) -o $(TEST_KV_MT) -lmount -lrdmacm -libverbs $(UCX_LIBS)
5252
else
5353
$(TEST_KV_MT):
5454
@echo "UCX not available, skip $(TEST_KV_MT)"
@@ -62,7 +62,7 @@ $(TEST_ACL): $(OBJS)
6262

6363
ifeq ($(shell pkg-config --exists ucx; echo $$?),0)
6464
$(TEST_KV_EXPIRE_ROUTINE): $(OBJS)
65-
$(CC) test_kv_expire_routine.c ../../lib/workqueue.c ../../lib/threads.c ../../lib/event.c ../../lib/ucx.c ../memory.c ../kv.c ../slab.c ../buddy.c ../crc.c ../../lib/log.c ../backend/backend.c ../transport/transport.c ../transport/rdma.c ../transport/ucx.c ../tiering.c ../acl.c $(CFLAGS) $(UCX_CFLAGS) -o $(TEST_KV_EXPIRE_ROUTINE) -lmount -lpthread -lrdmacm -libverbs $(UCX_LIBS)
65+
$(CC) test_kv_expire_routine.c ../../lib/workqueue.c ../../lib/threads.c ../../lib/event.c ../../lib/ucx.c ../../lib/config.c ../memory.c ../kv.c ../slab.c ../buddy.c ../crc.c ../../lib/log.c ../backend/backend.c ../transport/transport.c ../transport/rdma.c ../transport/ucx.c ../tiering.c ../acl.c $(CFLAGS) $(UCX_CFLAGS) -o $(TEST_KV_EXPIRE_ROUTINE) -lmount -lpthread -lrdmacm -libverbs $(UCX_LIBS)
6666
else
6767
$(TEST_KV_EXPIRE_ROUTINE):
6868
@echo "UCX not available, skip $(TEST_KV_EXPIRE_ROUTINE)"

server/transport/transport.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <strings.h>
1717

1818
#include "../kv.h"
19+
#include "priskv-config.h"
1920
#include "priskv-event.h"
2021
#include "priskv-log.h"
2122
#include "priskv-threads.h"
@@ -42,17 +43,9 @@ void priskv_tiering_del(priskv_tiering_req *treq);
4243

4344
static void __attribute__((constructor)) priskv_server_transport_init(void)
4445
{
45-
const char *transport_env = getenv("PRISKV_TRANSPORT");
46-
priskv_transport_backend backend = PRISKV_TRANSPORT_BACKEND_RDMA;
47-
if (transport_env) {
48-
if (strcasecmp(transport_env, "UCX") == 0) {
49-
backend = PRISKV_TRANSPORT_BACKEND_UCX;
50-
} else if (strcasecmp(transport_env, "RDMA") == 0) {
51-
backend = PRISKV_TRANSPORT_BACKEND_RDMA;
52-
} else {
53-
priskv_log_error("Unknown transport backend: %s\n", transport_env);
54-
}
55-
}
46+
priskv_config_init();
47+
48+
priskv_transport_backend backend = g_config.transport;
5649

5750
priskv_transport_driver *driver = NULL;
5851
switch (backend) {
@@ -78,10 +71,7 @@ static void __attribute__((constructor)) priskv_server_transport_init(void)
7871

7972
if (driver) {
8073
g_transport_driver = driver;
81-
return 0;
8274
}
83-
84-
return -1;
8575
}
8676

8777
int priskv_transport_listen(char **addr, int naddr, int port, void *kv,

0 commit comments

Comments
 (0)