Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENH] Add rust protobufs and conversion. Add build.rs, protobufs, and conversions #1513

Merged
merged 5 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/chroma-worker-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Protoc
uses: arduino/setup-protoc@v2
- name: Build
run: cargo build --verbose
- name: Test
Expand Down
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions rust/worker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ edition = "2021"

[dependencies]
tonic = "0.10"
prost = "0.12"
prost-types = "0.12"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
tokio-util = "0.7.10"
rand = "0.8.5"
Expand All @@ -16,6 +18,7 @@ serde = { version = "1.0.193", features = ["derive"] }
num_cpus = "1.16.0"
murmur3 = "0.5.2"
thiserror = "1.0.50"
num-bigint = "0.4.4"

[build-dependencies]
tonic-build = "0.10"
Expand Down
8 changes: 7 additions & 1 deletion rust/worker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
FROM rust:1.74.1 as builder

WORKDIR /chroma
WORKDIR /chroma/
COPY . .

ENV PROTOC_ZIP=protoc-25.1-linux-x86_64.zip
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v25.1/$PROTOC_ZIP \
&& unzip -o $PROTOC_ZIP -d /usr/local bin/protoc \
&& unzip -o $PROTOC_ZIP -d /usr/local 'include/*' \
&& rm -f $PROTOC_ZIP

RUN cargo build

# For now this runs cargo test since we have no main binary
Expand Down
10 changes: 10 additions & 0 deletions rust/worker/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure().compile(
&[
"../../idl/chromadb/proto/chroma.proto",
"../../idl/chromadb/proto/coordinator.proto",
],
&["../../idl/"],
)?;
Ok(())
}
3 changes: 3 additions & 0 deletions rust/worker/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ impl RootConfig {
/// ## Description of parameters
/// - my_ip: The IP address of the worker service. Used for memberlist assignment. Must be provided
/// - num_indexing_threads: The number of indexing threads to use. If not provided, defaults to the number of cores on the machine.
/// - pulsar_tenant: The pulsar tenant to use. Must be provided.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

clean up

/// - pulsar_namespace: The pulsar namespace to use. Must be provided.
/// - assignment_policy: The assignment policy to use. Must be provided.
/// # Notes
/// In order to set the enviroment variables, you must prefix them with CHROMA_WORKER__<FIELD_NAME>.
/// For example, to set my_ip, you would set CHROMA_WORKER__MY_IP.
Expand Down
5 changes: 5 additions & 0 deletions rust/worker/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
mod assignment;
mod config;
mod errors;
mod types;

mod chroma_proto {
tonic::include_proto!("chroma");
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This links the built proto

}
88 changes: 88 additions & 0 deletions rust/worker/src/types/collection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use super::{Metadata, MetadataValueConversionError};
use crate::{
chroma_proto,
errors::{ChromaError, ErrorCodes},
};
use thiserror::Error;
use uuid::Uuid;

#[derive(Debug, PartialEq)]
pub(crate) struct Collection {
pub(crate) id: Uuid,
pub(crate) name: String,
pub(crate) topic: String,
pub(crate) metadata: Option<Metadata>,
pub(crate) dimension: Option<i32>,
pub(crate) tenant: String,
pub(crate) database: String,
}

#[derive(Error, Debug)]
pub(crate) enum CollectionConversionError {
#[error("Invalid UUID")]
InvalidUuid,
#[error(transparent)]
MetadataValueConversionError(#[from] MetadataValueConversionError),
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Example of wrapping an error

}

impl ChromaError for CollectionConversionError {
HammadB marked this conversation as resolved.
Show resolved Hide resolved
fn code(&self) -> crate::errors::ErrorCodes {
match self {
CollectionConversionError::InvalidUuid => ErrorCodes::InvalidArgument,
CollectionConversionError::MetadataValueConversionError(e) => e.code(),
}
}
}

impl TryFrom<chroma_proto::Collection> for Collection {
type Error = CollectionConversionError;

fn try_from(proto_collection: chroma_proto::Collection) -> Result<Self, Self::Error> {
let collection_uuid = match Uuid::try_parse(&proto_collection.id) {
Ok(uuid) => uuid,
Err(_) => return Err(CollectionConversionError::InvalidUuid),
};
let collection_metadata: Option<Metadata> = match proto_collection.metadata {
Some(proto_metadata) => match proto_metadata.try_into() {
Ok(metadata) => Some(metadata),
Err(e) => return Err(CollectionConversionError::MetadataValueConversionError(e)),
},
None => None,
};
Ok(Collection {
id: collection_uuid,
name: proto_collection.name,
topic: proto_collection.topic,
metadata: collection_metadata,
dimension: proto_collection.dimension,
tenant: proto_collection.tenant,
database: proto_collection.database,
})
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_collection_try_from() {
let proto_collection = chroma_proto::Collection {
id: "00000000-0000-0000-0000-000000000000".to_string(),
name: "foo".to_string(),
topic: "bar".to_string(),
metadata: None,
dimension: None,
tenant: "baz".to_string(),
database: "qux".to_string(),
};
let converted_collection: Collection = proto_collection.try_into().unwrap();
assert_eq!(converted_collection.id, Uuid::nil());
assert_eq!(converted_collection.name, "foo".to_string());
assert_eq!(converted_collection.topic, "bar".to_string());
assert_eq!(converted_collection.metadata, None);
assert_eq!(converted_collection.dimension, None);
assert_eq!(converted_collection.tenant, "baz".to_string());
assert_eq!(converted_collection.database, "qux".to_string());
}
}
Loading