Skip to content

feat(db): add db cluster logic and tests#338

Open
jimezesinachi wants to merge 4 commits into
mainfrom
feat/replication-m1-db-integration
Open

feat(db): add db cluster logic and tests#338
jimezesinachi wants to merge 4 commits into
mainfrom
feat/replication-m1-db-integration

Conversation

@jimezesinachi

Copy link
Copy Markdown
Collaborator

No description provided.

Signed-off-by: Jim Ezesinachi <ezesinachijim@gmail.com>
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

Test Results

337 tests   337 ✅  20m 29s ⏱️
 41 suites    0 💤
  3 files      0 ❌

Results for commit 0f68992.

♻️ This comment has been updated with latest results.

Signed-off-by: Jim Ezesinachi <ezesinachijim@gmail.com>
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

Benchmark Results

group                                                        main                                   pr
-----                                                        ----                                   --
predicate_query_with_index/size_100                          1.00      3.2±0.00µs        ? ?/sec    1.03      3.3±0.00µs        ? ?/sec
predicate_query_with_index/size_1000                         1.00     32.5±0.03µs        ? ?/sec    1.01     32.8±0.01µs        ? ?/sec
predicate_query_with_index/size_10000                        1.00    331.0±0.36µs        ? ?/sec    1.00    329.4±0.33µs        ? ?/sec
predicate_query_with_index/size_100000                       1.01      9.5±0.51ms        ? ?/sec    1.00      9.4±0.89ms        ? ?/sec
predicate_query_without_index/size_100                       1.05      6.8±0.01µs        ? ?/sec    1.00      6.5±0.01µs        ? ?/sec
predicate_query_without_index/size_1000                      1.01     68.3±0.07µs        ? ?/sec    1.00     67.6±0.04µs        ? ?/sec
predicate_query_without_index/size_10000                     1.00    792.1±8.56µs        ? ?/sec    1.01    796.3±1.47µs        ? ?/sec
predicate_query_without_index/size_100000                    1.00     17.5±0.23ms        ? ?/sec    1.00     17.6±0.34ms        ? ?/sec
store_batch_insertion_without_predicates/size_100            1.02    227.3±1.51µs        ? ?/sec    1.00    222.2±2.09µs        ? ?/sec
store_batch_insertion_without_predicates/size_1000           1.00   1533.1±7.88µs        ? ?/sec    1.05  1605.2±24.21µs        ? ?/sec
store_batch_insertion_without_predicates/size_10000          1.00     18.2±0.08ms        ? ?/sec    1.02     18.6±0.19ms        ? ?/sec
store_batch_insertion_without_predicates/size_100000         1.00    181.8±0.84ms        ? ?/sec    1.00    181.1±1.53ms        ? ?/sec
store_retrieval_linear_cosine_similarity/size_100            1.04     93.8±1.23µs        ? ?/sec    1.00     90.3±1.06µs        ? ?/sec
store_retrieval_linear_cosine_similarity/size_1000           1.01    712.5±4.25µs        ? ?/sec    1.00    708.1±2.55µs        ? ?/sec
store_retrieval_linear_cosine_similarity/size_10000          1.01      7.6±0.02ms        ? ?/sec    1.00      7.5±0.03ms        ? ?/sec
store_retrieval_linear_cosine_similarity/size_100000         1.01     79.2±0.15ms        ? ?/sec    1.00     78.7±0.21ms        ? ?/sec
store_retrieval_linear_dot_product/size_100                  1.09     97.3±1.31µs        ? ?/sec    1.00     89.3±0.80µs        ? ?/sec
store_retrieval_linear_dot_product/size_1000                 1.00    707.9±2.26µs        ? ?/sec    1.00    706.3±3.39µs        ? ?/sec
store_retrieval_linear_dot_product/size_10000                1.00      7.3±0.07ms        ? ?/sec    1.02      7.4±0.04ms        ? ?/sec
store_retrieval_linear_dot_product/size_100000               1.00     77.2±0.16ms        ? ?/sec    1.00     77.1±0.23ms        ? ?/sec
store_retrieval_linear_euclidean_distance/size_100           1.05     93.9±0.86µs        ? ?/sec    1.00     89.8±0.97µs        ? ?/sec
store_retrieval_linear_euclidean_distance/size_1000          1.01    709.6±4.16µs        ? ?/sec    1.00    703.6±3.14µs        ? ?/sec
store_retrieval_linear_euclidean_distance/size_10000         1.00      7.3±0.05ms        ? ?/sec    1.02      7.5±0.04ms        ? ?/sec
store_retrieval_linear_euclidean_distance/size_100000        1.01     78.4±0.31ms        ? ?/sec    1.00     77.8±0.31ms        ? ?/sec
store_retrieval_no_condition/size_100                        1.01     91.8±0.93µs        ? ?/sec    1.00     91.3±1.33µs        ? ?/sec
store_retrieval_no_condition/size_1000                       1.00    709.7±4.21µs        ? ?/sec    1.01    714.0±3.55µs        ? ?/sec
store_retrieval_no_condition/size_10000                      1.00      7.3±0.04ms        ? ?/sec    1.03      7.5±0.04ms        ? ?/sec
store_retrieval_no_condition/size_100000                     1.00     78.7±0.19ms        ? ?/sec    1.05     82.3±0.29ms        ? ?/sec
store_retrieval_non_linear_hnsw/size_100                     1.00    130.0±1.60µs        ? ?/sec    1.00    129.7±1.07µs        ? ?/sec
store_retrieval_non_linear_hnsw/size_1000                    1.00    560.1±7.82µs        ? ?/sec    1.00   560.2±11.84µs        ? ?/sec
store_retrieval_non_linear_hnsw/size_10000                   1.00      2.3±0.06ms        ? ?/sec    1.06      2.5±0.10ms        ? ?/sec
store_retrieval_non_linear_hnsw/size_100000                  1.00     17.1±0.29ms        ? ?/sec    1.06     18.2±0.21ms        ? ?/sec
store_retrieval_non_linear_kdtree/size_100                   1.00    193.1±0.52µs        ? ?/sec    1.00    192.9±1.34µs        ? ?/sec
store_retrieval_non_linear_kdtree/size_1000                  1.00   1393.1±1.45µs        ? ?/sec    1.00   1394.2±3.53µs        ? ?/sec
store_retrieval_non_linear_kdtree/size_10000                 1.00     15.4±0.12ms        ? ?/sec    1.02     15.7±0.15ms        ? ?/sec
store_retrieval_non_linear_kdtree/size_100000                1.00    173.0±0.20ms        ? ?/sec    1.02    175.6±0.30ms        ? ?/sec
store_sequential_insertion_without_predicates/size_100       1.00    268.3±0.49µs        ? ?/sec    1.00    267.6±0.47µs        ? ?/sec
store_sequential_insertion_without_predicates/size_1000      1.00      2.7±0.00ms        ? ?/sec    1.00      2.7±0.00ms        ? ?/sec
store_sequential_insertion_without_predicates/size_10000     1.00     26.9±0.08ms        ? ?/sec    1.00     26.8±0.08ms        ? ?/sec
store_sequential_insertion_without_predicates/size_100000    1.01    270.3±0.35ms        ? ?/sec    1.00    268.3±0.42ms        ? ?/sec

Comment thread ahnlich/db/src/server/handler.rs Outdated
client_handler: Arc<ClientHandler>,
task_manager: Arc<TaskManager>,
config: ServerConfig,
cluster: Option<ClusterRuntime>,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterRuntime would ideally always contain store_handler.... and we typically only ever want to access store_handler directly independent of cluster if cluster doesn't exist? Seems like we should have a cleaner

enum StoreRuntime {
    Standalone(StoreHandler), // perhaps a more befitting rename to handler/ runtime to be consistent
    Cluster(ClusterRuntime), 
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually agree with this, I went in the direction of not changing the shape of Server, but this is the better direction long term

}

pub(crate) async fn list_stores_response(
cluster: Option<&ClusterRuntime>,

@deven96 deven96 Jun 9, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not particularly sold on having optional cluster and a reference to store_handler when cluster always contains handler... see above comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A'firm, I will change the shape now


fn task_manager(&self) -> Arc<TaskManager>;

fn should_spawn_persistence(&self) -> bool {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIXME on this so we don't forget while implementing AI db cluster logic

Comment thread ahnlich/db/src/tests/cluster_tests.rs

@deven96 deven96 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments

Comment thread ahnlich/db/src/server/handler.rs

fn apply(&mut self, data: &DbCommand) -> Result<DbResponse, StorageError<u64>> {
match data {
DbCommand::CreateStore(payload) => {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's probably a nice way to turn decode_payload into a macro so we dont have to manually pass that string but can extract it from the ty via stringify!

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like

macro_rules! decode_payload {
    ($ty:ty, $payload:expr) => {{
        <$ty>::decode($payload).map_err(|err| StorageError::IO {
            source: StorageIOError::read_state_machine(&std::io::Error::other(format!(
                "failed to decode {} raft payload: {}",
                stringify!($ty),
                err,
            ))),
        })
    }};
}

let params: query::CreateStore =
    decode_payload!(query::CreateStore, payload)?;

use std::any::{Any, TypeId};

pub(crate) fn map_client_write_error(
command_name: &str,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another good use of macros to enforce not needing command name alongside the actual command

Comment thread ahnlich/db/Cargo.toml
prost.workspace = true
openraft.workspace = true
ahnlich-replication = { path = "../replication", version = "*" }
bitcode = { version = "0.6", features = ["serde"] }

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should move to general Cargo.toml... my suspicion is we will reuse elsewhere

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants