From 331039d0347b1d25b1289a54ac45960cce77ded3 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Sun, 17 May 2026 19:53:24 -0700 Subject: [PATCH 01/14] Add test case that enables shared memory TODO - valgrind shows an uninitialized read when testing shm locally --- test/new_tests/test_shared_memory.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 test/new_tests/test_shared_memory.py diff --git a/test/new_tests/test_shared_memory.py b/test/new_tests/test_shared_memory.py new file mode 100644 index 0000000000..fe520e3d57 --- /dev/null +++ b/test/new_tests/test_shared_memory.py @@ -0,0 +1,11 @@ +import aerospike + + +class TestSharedMemory: + def test_one_client(self): + self.connection_config["use_shared_connection"] = True + client = aerospike.client(self.connection_config) + + assert client.is_connected() + + client.close() From 1bb838d5f9c3833d2080c39f05ed3a0119b0e28f Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Sun, 17 May 2026 19:27:40 -0700 Subject: [PATCH 02/14] update C client to get Gagan's fix for the shmem uninitialized read --- aerospike-client-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aerospike-client-c b/aerospike-client-c index 48203a3e96..994e9fe323 160000 --- a/aerospike-client-c +++ b/aerospike-client-c @@ -1 +1 @@ -Subproject commit 48203a3e96480022dcb74ba85cae2a6ac5fb5fd6 +Subproject commit 994e9fe323ebc2b2628a0bbff3458263901ae6be From 2b76744758579d477a7dc1de65df12e84aa3d470 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Sun, 17 May 2026 19:31:41 -0700 Subject: [PATCH 03/14] Update internal macro names from the C client --- aerospike_helpers/expressions/map.py | 4 ++-- src/main/aerospike.c | 4 ++-- src/main/convert_expressions.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aerospike_helpers/expressions/map.py b/aerospike_helpers/expressions/map.py index ac6623705f..9f00791e58 100644 --- a/aerospike_helpers/expressions/map.py +++ b/aerospike_helpers/expressions/map.py @@ -1495,7 +1495,7 @@ class MapGetKeys(_BaseExpr): Return a list of keys from a map. """ - _op = aerospike._AS_EXP_CODE_MAP_KEYS + _op = aerospike._AS_EXP_CODE_MAP_KEYS_IN def __init__( self, @@ -1516,7 +1516,7 @@ class MapGetValues(_BaseExpr): Return a list of values from a map. """ - _op = aerospike._AS_EXP_CODE_MAP_VALUES + _op = aerospike._AS_EXP_CODE_MAP_VALUES_IN def __init__( self, diff --git a/src/main/aerospike.c b/src/main/aerospike.c index 8cd3eaf7f5..0a193b4081 100644 --- a/src/main/aerospike.c +++ b/src/main/aerospike.c @@ -590,8 +590,8 @@ static struct module_constant_name_to_value module_constants[] = { EXPOSE_MACRO(_AS_EXP_CODE_REMOVE_RESULT), EXPOSE_MACRO(_AS_EXP_CODE_IN_LIST), - EXPOSE_MACRO(_AS_EXP_CODE_MAP_KEYS), - EXPOSE_MACRO(_AS_EXP_CODE_MAP_VALUES), + EXPOSE_MACRO(_AS_EXP_CODE_MAP_KEYS_IN), + EXPOSE_MACRO(_AS_EXP_CODE_MAP_VALUES_IN), EXPOSE_STRING_MACRO_FOR_AEROSPIKE_HELPERS(_CDT_FLAGS_KEY), EXPOSE_STRING_MACRO_FOR_AEROSPIKE_HELPERS(_CDT_APPLY_MOD_EXP_KEY), diff --git a/src/main/convert_expressions.c b/src/main/convert_expressions.c index c3a595b77c..0fad784799 100644 --- a/src/main/convert_expressions.c +++ b/src/main/convert_expressions.c @@ -351,8 +351,8 @@ static as_status get_expr_size(int *size_to_alloc, int *intermediate_exprs_size, [OP_MAP_SIZE] = EXP_SZ(as_exp_map_size(NULL, NIL)), [OP_MAP_GET_BY_KEY] = EXP_SZ(as_exp_map_get_by_key(NULL, 0, 0, NIL, NIL)), - [_AS_EXP_CODE_MAP_KEYS] = EXP_SZ(as_exp_map_keys(NIL)), - [_AS_EXP_CODE_MAP_VALUES] = EXP_SZ(as_exp_map_values(NIL)), + [_AS_EXP_CODE_MAP_KEYS_IN] = EXP_SZ(as_exp_map_keys(NIL)), + [_AS_EXP_CODE_MAP_VALUES_IN] = EXP_SZ(as_exp_map_values(NIL)), [OP_MAP_SIZE] = EXP_SZ(as_exp_map_size(NULL, NIL)), [OP_MAP_GET_BY_KEY_RANGE] = EXP_SZ(as_exp_map_get_by_key_range(NULL, 0, NIL, NIL, NIL)), @@ -1245,10 +1245,10 @@ add_expr_macros(AerospikeClient *self, as_static_pool *static_pool, APPEND_ARRAY(1, as_exp_map_size(temp_expr->ctx, NIL)); // - 1 for bin break; - case _AS_EXP_CODE_MAP_KEYS: + case _AS_EXP_CODE_MAP_KEYS_IN: APPEND_ARRAY(1, as_exp_map_keys(NIL)); // - 1 for bin break; - case _AS_EXP_CODE_MAP_VALUES: + case _AS_EXP_CODE_MAP_VALUES_IN: APPEND_ARRAY(1, as_exp_map_values(NIL)); // - 1 for bin break; case OP_MAP_GET_BY_KEY: From afdc3eb322f0ff9e4590ed2a7e7fd99b269a8e8a Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 10:11:39 -0700 Subject: [PATCH 04/14] Try updating as_exp_map_* macros to resolve compiler errors --- src/main/convert_expressions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/convert_expressions.c b/src/main/convert_expressions.c index 0fad784799..40bb1a75ee 100644 --- a/src/main/convert_expressions.c +++ b/src/main/convert_expressions.c @@ -351,8 +351,8 @@ static as_status get_expr_size(int *size_to_alloc, int *intermediate_exprs_size, [OP_MAP_SIZE] = EXP_SZ(as_exp_map_size(NULL, NIL)), [OP_MAP_GET_BY_KEY] = EXP_SZ(as_exp_map_get_by_key(NULL, 0, 0, NIL, NIL)), - [_AS_EXP_CODE_MAP_KEYS_IN] = EXP_SZ(as_exp_map_keys(NIL)), - [_AS_EXP_CODE_MAP_VALUES_IN] = EXP_SZ(as_exp_map_values(NIL)), + [_AS_EXP_CODE_MAP_KEYS_IN] = EXP_SZ(as_exp_map_keys_in(NIL)), + [_AS_EXP_CODE_MAP_VALUES_IN] = EXP_SZ(as_exp_map_values_in(NIL)), [OP_MAP_SIZE] = EXP_SZ(as_exp_map_size(NULL, NIL)), [OP_MAP_GET_BY_KEY_RANGE] = EXP_SZ(as_exp_map_get_by_key_range(NULL, 0, NIL, NIL, NIL)), From 82f51f9237903b2aa4fc1ddcc35ac09f27060ff9 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 10:14:47 -0700 Subject: [PATCH 05/14] Also update macros further down the code path --- src/main/convert_expressions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/convert_expressions.c b/src/main/convert_expressions.c index 40bb1a75ee..6c52330785 100644 --- a/src/main/convert_expressions.c +++ b/src/main/convert_expressions.c @@ -1246,10 +1246,10 @@ add_expr_macros(AerospikeClient *self, as_static_pool *static_pool, NIL)); // - 1 for bin break; case _AS_EXP_CODE_MAP_KEYS_IN: - APPEND_ARRAY(1, as_exp_map_keys(NIL)); // - 1 for bin + APPEND_ARRAY(1, as_exp_map_keys_in(NIL)); // - 1 for bin break; case _AS_EXP_CODE_MAP_VALUES_IN: - APPEND_ARRAY(1, as_exp_map_values(NIL)); // - 1 for bin + APPEND_ARRAY(1, as_exp_map_values_in(NIL)); // - 1 for bin break; case OP_MAP_GET_BY_KEY: if (get_int64_t(err, AS_PY_MAP_RETURN_KEY, temp_expr->pydict, From 10ffbfa3f57c6e963c28a56e34f961b2d6824ee0 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 10:17:30 -0700 Subject: [PATCH 06/14] Address test syntax failing --- test/new_tests/test_shared_memory.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/new_tests/test_shared_memory.py b/test/new_tests/test_shared_memory.py index fe520e3d57..e780ff130c 100644 --- a/test/new_tests/test_shared_memory.py +++ b/test/new_tests/test_shared_memory.py @@ -1,6 +1,8 @@ import aerospike +import pytest +@pytest.mark.usefixtures("connection_config") class TestSharedMemory: def test_one_client(self): self.connection_config["use_shared_connection"] = True From eb6a5c095511116924ea9c535230b366619b335b Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 10:28:38 -0700 Subject: [PATCH 07/14] Add 2nd test case where multiple clients share the same shared memory --- test/new_tests/test_shared_memory.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/new_tests/test_shared_memory.py b/test/new_tests/test_shared_memory.py index e780ff130c..7bceb13fa5 100644 --- a/test/new_tests/test_shared_memory.py +++ b/test/new_tests/test_shared_memory.py @@ -11,3 +11,15 @@ def test_one_client(self): assert client.is_connected() client.close() + + def test_multiple_clients(self): + self.connection_config["use_shared_connection"] = True + + client1 = aerospike.client(self.connection_config) + assert client1.is_connected() + + client2 = aerospike.client(self.connection_config) + assert client2.is_connected() + + client1.close() + client2.close() From 3fe572581637bbedbc156e975ad8793c10a1b0c5 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 10:34:40 -0700 Subject: [PATCH 08/14] Address bad test syntax. Also make sure shm is enabled --- test/new_tests/test_shared_memory.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/new_tests/test_shared_memory.py b/test/new_tests/test_shared_memory.py index 7bceb13fa5..cd65082ac0 100644 --- a/test/new_tests/test_shared_memory.py +++ b/test/new_tests/test_shared_memory.py @@ -4,8 +4,12 @@ @pytest.mark.usefixtures("connection_config") class TestSharedMemory: + @pytest.fixture(autouse=True) + def setup(self): + self.__class__.connection_config["shm"] = {} + self.__class__.connection_config["use_shared_connection"] = True + def test_one_client(self): - self.connection_config["use_shared_connection"] = True client = aerospike.client(self.connection_config) assert client.is_connected() @@ -13,7 +17,6 @@ def test_one_client(self): client.close() def test_multiple_clients(self): - self.connection_config["use_shared_connection"] = True client1 = aerospike.client(self.connection_config) assert client1.is_connected() From 4d2397a22f3a3148f1bd15229afa7f9100a0f3ad Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 14:27:27 -0700 Subject: [PATCH 09/14] Update hardcoded shmem key to address abort crash in c client's as_poll_socket -> FD_SET() where fd is -1. --- src/main/aerospike.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/aerospike.c b/src/main/aerospike.c index 0a193b4081..0b6fdb17aa 100644 --- a/src/main/aerospike.c +++ b/src/main/aerospike.c @@ -45,7 +45,7 @@ #include PyObject *py_global_hosts = NULL; -int counter = 0xA8000000; +int counter = 0xA1100000; bool user_shm_key = false; PyDoc_STRVAR(client_doc, "client(config) -> client object\n\ From b15cda4ea84e874d93d93088b382ce42adb47161 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 14:54:35 -0700 Subject: [PATCH 10/14] Use shm key that is hardcoded in as_config_init's implementation. The one in the docstring for as_config doesn't match the implementation --- src/main/aerospike.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/aerospike.c b/src/main/aerospike.c index 0b6fdb17aa..9d6c586607 100644 --- a/src/main/aerospike.c +++ b/src/main/aerospike.c @@ -45,7 +45,7 @@ #include PyObject *py_global_hosts = NULL; -int counter = 0xA1100000; +int counter = 0xAC000000; bool user_shm_key = false; PyDoc_STRVAR(client_doc, "client(config) -> client object\n\ From aec7da9a39b1e4da60d1522040a9ba97dac1ca78 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 19 May 2026 15:06:29 -0700 Subject: [PATCH 11/14] Now we see that setting python client default shm key to 0xAC000000 stops the test from crashing, remove this default shm key so we don't need to manually update it if the c client updates the default one (e.g in this PR) --- src/include/types.h | 1 - src/main/aerospike.c | 1 - src/main/client/connect.c | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/include/types.h b/src/include/types.h index 7397e9aebc..5369688d7c 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -36,7 +36,6 @@ // Bin names can be of type Unicode in Python // DB supports 32767 maximum number of bins #define MAX_UNICODE_OBJECTS 32767 -extern int counter; extern PyObject *py_global_hosts; extern bool user_shm_key; diff --git a/src/main/aerospike.c b/src/main/aerospike.c index 9d6c586607..96683ea97b 100644 --- a/src/main/aerospike.c +++ b/src/main/aerospike.c @@ -45,7 +45,6 @@ #include PyObject *py_global_hosts = NULL; -int counter = 0xAC000000; bool user_shm_key = false; PyDoc_STRVAR(client_doc, "client(config) -> client object\n\ diff --git a/src/main/client/connect.c b/src/main/client/connect.c index 54f0e0cb26..5d206dce11 100644 --- a/src/main/client/connect.c +++ b/src/main/client/connect.c @@ -95,9 +95,7 @@ int AerospikeClientConnect(AerospikeClient *self) shm_key = self->as->config.shm_key; user_shm_key = false; } - else { - shm_key = counter; - } + while (1) { flag = 0; while (PyDict_Next(py_global_hosts, &pos, &py_key, &py_value)) { From 0cbc1783d5c267f346de371264f27260e040c7bd Mon Sep 17 00:00:00 2001 From: juliannguyen4 <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 20 May 2026 02:12:52 +0000 Subject: [PATCH 12/14] Revert "Now we see that setting python client default shm key to 0xAC000000 stops the test from crashing, remove this default shm key so we don't need to manually update it if the c client updates the default one (e.g in this PR)" This reverts commit aec7da9a39b1e4da60d1522040a9ba97dac1ca78. --- src/include/types.h | 1 + src/main/aerospike.c | 1 + src/main/client/connect.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/include/types.h b/src/include/types.h index 5369688d7c..7397e9aebc 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -36,6 +36,7 @@ // Bin names can be of type Unicode in Python // DB supports 32767 maximum number of bins #define MAX_UNICODE_OBJECTS 32767 +extern int counter; extern PyObject *py_global_hosts; extern bool user_shm_key; diff --git a/src/main/aerospike.c b/src/main/aerospike.c index 96683ea97b..9d6c586607 100644 --- a/src/main/aerospike.c +++ b/src/main/aerospike.c @@ -45,6 +45,7 @@ #include PyObject *py_global_hosts = NULL; +int counter = 0xAC000000; bool user_shm_key = false; PyDoc_STRVAR(client_doc, "client(config) -> client object\n\ diff --git a/src/main/client/connect.c b/src/main/client/connect.c index 5d206dce11..54f0e0cb26 100644 --- a/src/main/client/connect.c +++ b/src/main/client/connect.c @@ -95,7 +95,9 @@ int AerospikeClientConnect(AerospikeClient *self) shm_key = self->as->config.shm_key; user_shm_key = false; } - + else { + shm_key = counter; + } while (1) { flag = 0; while (PyDict_Next(py_global_hosts, &pos, &py_key, &py_value)) { From b957531a6abf13e77fc94e1461eedf03c4a15eff Mon Sep 17 00:00:00 2001 From: juliannguyen4 <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 20 May 2026 02:24:14 +0000 Subject: [PATCH 13/14] use_shared_connection causes multiple clients to share the same C client instance if they use the same host seeds --- test/new_tests/test_shared_memory.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/new_tests/test_shared_memory.py b/test/new_tests/test_shared_memory.py index cd65082ac0..2a913ec602 100644 --- a/test/new_tests/test_shared_memory.py +++ b/test/new_tests/test_shared_memory.py @@ -7,7 +7,6 @@ class TestSharedMemory: @pytest.fixture(autouse=True) def setup(self): self.__class__.connection_config["shm"] = {} - self.__class__.connection_config["use_shared_connection"] = True def test_one_client(self): client = aerospike.client(self.connection_config) From 8bba73b0522708af47f85736445af5cc0a56a7ea Mon Sep 17 00:00:00 2001 From: juliannguyen4 <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 20 May 2026 21:05:18 +0000 Subject: [PATCH 14/14] Pull c client fix to address shared memory crash --- .gitmodules | 2 +- aerospike-client-c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 136ba68cbe..4aea533e0c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,4 +2,4 @@ path = aerospike-client-c # url = git@github.com:aerospike/aerospike-client-c.git url = https://github.com/aerospike/aerospike-client-c.git - branch = stage + branch = CLIENT-4844 diff --git a/aerospike-client-c b/aerospike-client-c index 994e9fe323..3b4e7512d2 160000 --- a/aerospike-client-c +++ b/aerospike-client-c @@ -1 +1 @@ -Subproject commit 994e9fe323ebc2b2628a0bbff3458263901ae6be +Subproject commit 3b4e7512d2daa146d8424d49761f902b40cde3d4