From 543435d6472555992c954fd9ba0be23fe07a8bec Mon Sep 17 00:00:00 2001 From: Ben Steer Date: Wed, 6 Nov 2024 15:53:00 +0000 Subject: [PATCH] Adding initial docker files (#1836) * Adding initial docker files * impl review comments and add server config debug log * add server config debug log * Updates from #1844, add more configs to server * more changes from #1844 * make server configs parsable as args * make makefile accept args to pass to graphqlserver * fix python docker * add package and rust version as label and add dockerignore * add github workflow * deactivate storage * extract rust and package versions * impl review comments * fix pacakge name * upgrade rust * levelup rust ver * fix build --------- Co-authored-by: Ben Steer Co-authored-by: Shivam Kapoor <4599890+iamsmkr@users.noreply.github.com> Co-authored-by: Shivam <4599890+shivam-880@users.noreply.github.com> --- .dockerignore | 2 + .github/workflows/_release_dockerhub.yml | 75 ++++++++++++++ .../workflows/manual_release_dockerhub.yml | 20 ++++ .github/workflows/release_auto.yml | 6 ++ Cargo.lock | 1 + Dockerfile | 11 +-- Makefile | 99 ++++++++++++++++++- docker/.dockerignore | 8 ++ docker/base/Dockerfile | 29 ++++++ docker/dockerfile | 27 +++++ docker/server.py | 75 ++++++++++++++ raphtory-graphql/Cargo.toml | 1 + raphtory-graphql/resources/index.html | 2 +- raphtory-graphql/src/config/app_config.rs | 2 +- raphtory-graphql/src/config/cache_config.rs | 10 +- raphtory-graphql/src/config/log_config.rs | 6 +- raphtory-graphql/src/config/otlp_config.rs | 17 +++- raphtory-graphql/src/data.rs | 2 +- raphtory-graphql/src/main.rs | 75 +++++++++++--- raphtory-graphql/src/server.rs | 12 ++- 20 files changed, 445 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/_release_dockerhub.yml create mode 100644 .github/workflows/manual_release_dockerhub.yml create mode 100644 docker/.dockerignore create mode 100644 docker/base/Dockerfile create mode 100644 docker/dockerfile create mode 100644 docker/server.py diff --git a/.dockerignore b/.dockerignore index 91296b6344..bafe553c20 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,5 @@ +pometry-storage-private +.dockerignore target/ .git/ .env diff --git a/.github/workflows/_release_dockerhub.yml b/.github/workflows/_release_dockerhub.yml new file mode 100644 index 0000000000..9a649e0521 --- /dev/null +++ b/.github/workflows/_release_dockerhub.yml @@ -0,0 +1,75 @@ +name: _Release 5 - Publish Docker Images to Docker Hub +on: + workflow_call: + +permissions: + contents: read + packages: write + +jobs: + publish-docker: + name: Build and Publish Docker Images + runs-on: ubuntu-latest + + steps: + - name: Check out the code + uses: actions/checkout@v3 + + - name: Extract Package and Rust Versions + id: version_extraction + run: | + PACKAGE_VERSION=$(grep -m 1 '^version' Cargo.toml | sed 's/version = "\(.*\)"/\1/') + RUST_VERSION=$(grep -m 1 '^rust-version' Cargo.toml | sed 's/rust-version = "\(.*\)"/\1/') + echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV + echo "RUST_VERSION=$RUST_VERSION" >> $GITHUB_ENV + shell: bash + + - name: Deactivate Private Storage + run: | + chmod +x ./scripts/deactivate_private_storage.py + ./scripts/deactivate_private_storage.py + + - name: Log in to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up QEMU for multi-platform builds + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push raphtory_base Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: docker/base/Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ secrets.DOCKERHUB_USERNAME }}/raphtory_base:${{ env.RUST_VERSION }} + ${{ secrets.DOCKERHUB_USERNAME }}/raphtory_base:latest + + - name: Build and push Python Docker image (pyraphtory) + uses: docker/build-push-action@v4 + with: + context: . + file: docker/dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ secrets.DOCKERHUB_USERNAME }}/pyraphtory:${{ env.PACKAGE_VERSION }} + ${{ secrets.DOCKERHUB_USERNAME }}/pyraphtory:latest + + - name: Build and push Rust Docker image (raphtory) + uses: docker/build-push-action@v4 + with: + context: . + file: Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ secrets.DOCKERHUB_USERNAME }}/raphtory:${{ env.PACKAGE_VERSION }} + ${{ secrets.DOCKERHUB_USERNAME }}/raphtory:latest diff --git a/.github/workflows/manual_release_dockerhub.yml b/.github/workflows/manual_release_dockerhub.yml new file mode 100644 index 0000000000..abdd1dfe84 --- /dev/null +++ b/.github/workflows/manual_release_dockerhub.yml @@ -0,0 +1,20 @@ +name: (Manual) Release Docker Hub +on: + workflow_dispatch: + inputs: + base: + description: 'Name of branch to open PR against' + type: 'string' + default: 'main' + dry_run: + description: 'DRY RUN: If true, will not publish the release to PyPI/crates/Docker Hub but will release to GitHub' + type: boolean + default: false + +jobs: + call-release-docker-workflow: + name: _Release 5 - Publish Docker Images to Docker Hub + uses: ./.github/workflows/_release_docker.yml + with: + version: ${{ inputs.base }} + secrets: inherit diff --git a/.github/workflows/release_auto.yml b/.github/workflows/release_auto.yml index c85a7956d5..fc3be32008 100644 --- a/.github/workflows/release_auto.yml +++ b/.github/workflows/release_auto.yml @@ -32,3 +32,9 @@ jobs: with: base: ${{ inputs.base }} secrets: inherit + call-release-docker-workflow: + name: _Release 5 - Publish Docker Images to Docker Hub + uses: ./.github/workflows/_release_docker.yml + with: + version: ${{ inputs.base }} + secrets: inherit diff --git a/Cargo.lock b/Cargo.lock index 3d2362e494..025c3b6639 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4767,6 +4767,7 @@ dependencies = [ "base64 0.22.1", "base64-compat", "chrono", + "clap", "config", "crossbeam-channel", "dynamic-graphql", diff --git a/Dockerfile b/Dockerfile index 3f3073b288..b87903d197 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,11 @@ -FROM rust:1.80.0 AS chef +FROM rust:1.82.0 AS chef RUN cargo install cargo-chef --version 0.1.67 WORKDIR /app FROM chef AS planner COPY . . +RUN sed -i '/default-members/d' Cargo.toml +RUN sed -i '/members = \[/,/\]/c\members = ["raphtory", "raphtory-graphql"]' Cargo.toml RUN cargo chef prepare --recipe-path recipe.json FROM chef AS builder @@ -11,15 +13,12 @@ RUN apt-get update RUN apt-get install -y protobuf-compiler COPY --from=planner /app/recipe.json recipe.json RUN cargo chef cook --release --recipe-path recipe.json -# RUN cargo chef cook --recipe-path recipe.json COPY . . RUN cargo build --release -p raphtory-graphql -# RUN cargo build -p raphtory-graphql -# FROM alpine:3.20.3 FROM debian:bookworm-slim ENV PORT=1736 COPY --from=builder /app/target/release/raphtory-graphql /raphtory-graphql -# COPY --from=builder /app/target/debug/raphtory-graphql /usr/local/bin/raphtory-graphql WORKDIR /graphs -CMD ["/raphtory-graphql"] + +ENTRYPOINT ["/raphtory-graphql"] diff --git a/Makefile b/Makefile index 92efb7a83a..070fb85dae 100644 --- a/Makefile +++ b/Makefile @@ -63,4 +63,101 @@ debug-python: activate-storage cd python && maturin develop --features=storage --extras=dev python-docs: - cd docs && make html \ No newline at end of file + cd docs && make html + +WORKING_DIR ?= /tmp/graphs +PORT ?= 1736 + +PACKAGE_VERSION := $(shell grep -m 1 '^version' Cargo.toml | sed 's/version = "\(.*\)"/\1/') +RUST_VERSION := $(shell grep -m 1 '^rust-version' Cargo.toml | sed 's/rust-version = "\(.*\)"/\1/') + +print-versions: + @echo "Package Version: $(PACKAGE_VERSION)" + @echo "Rust Version: $(RUST_VERSION)" + +BASE_IMAGE_NAME_AMD64 := pometry/raphtory_base:$(RUST_VERSION)-amd64 +BASE_IMAGE_NAME_ARM64 := pometry/raphtory_base:$(RUST_VERSION)-arm64 +IMAGE_NAME_AMD64 := pometry/raphtory:$(PACKAGE_VERSION)-rust-amd64 +IMAGE_NAME_ARM64 := pometry/raphtory:$(PACKAGE_VERSION)-rust-arm64 +PY_IMAGE_NAME_AMD64 := pometry/raphtory:$(PACKAGE_VERSION)-python-amd64 +PY_IMAGE_NAME_ARM64 := pometry/raphtory:$(PACKAGE_VERSION)-python-arm64 + +docker-build-pyraphtory-base-amd64: + cd docker/base && docker build --platform linux/amd64 -t $(BASE_IMAGE_NAME_AMD64) . + +docker-build-pyraphtory-base-arm64: + cd docker/base && docker build --platform linux/arm64 -t $(BASE_IMAGE_NAME_ARM64) . + +docker-build-pyraphtory-amd64: + ./scripts/deactivate_private_storage.py + docker build -f docker/dockerfile --build-arg BASE_IMAGE=$(BASE_IMAGE_NAME_AMD64) --platform linux/amd64 -t $(PY_IMAGE_NAME_AMD64) . + +docker-build-pyraphtory-arm64: + ./scripts/deactivate_private_storage.py + docker build -f docker/dockerfile --build-arg BASE_IMAGE=$(BASE_IMAGE_NAME_ARM64) --platform linux/arm64 -t $(PY_IMAGE_NAME_ARM64) . + +docker-build-raphtory-amd64: + ./scripts/deactivate_private_storage.py + docker build --platform linux/amd64 -t $(IMAGE_NAME_AMD64) . + +docker-build-raphtory-arm64: + ./scripts/deactivate_private_storage.py + docker build --platform linux/arm64 -t $(IMAGE_NAME_ARM64) . + +# Docker run targets for pyraphtory +docker-run-pyraphtory-amd64: + docker run --rm -p $(PORT):$(PORT) \ + -v $(WORKING_DIR):/tmp/graphs \ + $(PY_IMAGE_NAME_AMD64) \ + $(if $(WORKING_DIR),--working-dir=$(WORKING_DIR)) \ + $(if $(PORT),--port=$(PORT)) \ + $(if $(CACHE_CAPACITY),--cache-capacity=$(CACHE_CAPACITY)) \ + $(if $(CACHE_TTI_SECONDS),--cache-tti-seconds=$(CACHE_TTI_SECONDS)) \ + $(if $(LOG_LEVEL),--log-level=$(LOG_LEVEL)) \ + $(if $(TRACING),--tracing) \ + $(if $(OTLP_AGENT_HOST),--otlp-agent-host=$(OTLP_AGENT_HOST)) \ + $(if $(OTLP_AGENT_PORT),--otlp-agent-port=$(OTLP_AGENT_PORT)) \ + $(if $(OTLP_TRACING_SERVICE_NAME),--otlp-tracing-service-name=$(OTLP_TRACING_SERVICE_NAME)) + +docker-run-pyraphtory-arm64: + docker run --rm -p $(PORT):$(PORT) \ + -v $(WORKING_DIR):/tmp/graphs \ + $(PY_IMAGE_NAME_ARM64) \ + $(if $(WORKING_DIR),--working-dir=$(WORKING_DIR)) \ + $(if $(PORT),--port=$(PORT)) \ + $(if $(CACHE_CAPACITY),--cache-capacity=$(CACHE_CAPACITY)) \ + $(if $(CACHE_TTI_SECONDS),--cache-tti-seconds=$(CACHE_TTI_SECONDS)) \ + $(if $(LOG_LEVEL),--log-level=$(LOG_LEVEL)) \ + $(if $(TRACING),--tracing) \ + $(if $(OTLP_AGENT_HOST),--otlp-agent-host=$(OTLP_AGENT_HOST)) \ + $(if $(OTLP_AGENT_PORT),--otlp-agent-port=$(OTLP_AGENT_PORT)) \ + $(if $(OTLP_TRACING_SERVICE_NAME),--otlp-tracing-service-name=$(OTLP_TRACING_SERVICE_NAME)) + +# Docker run targets for raphtory +docker-run-raphtory-amd64: + docker run --rm -p $(PORT):$(PORT) \ + -v $(WORKING_DIR):/tmp/graphs \ + $(IMAGE_NAME_AMD64) \ + $(if $(WORKING_DIR),--working-dir=$(WORKING_DIR)) \ + $(if $(PORT),--port=$(PORT)) \ + $(if $(CACHE_CAPACITY),--cache-capacity=$(CACHE_CAPACITY)) \ + $(if $(CACHE_TTI_SECONDS),--cache-tti-seconds=$(CACHE_TTI_SECONDS)) \ + $(if $(LOG_LEVEL),--log-level=$(LOG_LEVEL)) \ + $(if $(TRACING),--tracing) \ + $(if $(OTLP_AGENT_HOST),--otlp-agent-host=$(OTLP_AGENT_HOST)) \ + $(if $(OTLP_AGENT_PORT),--otlp-agent-port=$(OTLP_AGENT_PORT)) \ + $(if $(OTLP_TRACING_SERVICE_NAME),--otlp-tracing-service-name=$(OTLP_TRACING_SERVICE_NAME)) + +docker-run-raphtory-arm64: + docker run --rm -p $(PORT):$(PORT) \ + -v $(WORKING_DIR):/tmp/graphs \ + $(IMAGE_NAME_ARM64) \ + $(if $(WORKING_DIR),--working-dir=$(WORKING_DIR)) \ + $(if $(PORT),--port=$(PORT)) \ + $(if $(CACHE_CAPACITY),--cache-capacity=$(CACHE_CAPACITY)) \ + $(if $(CACHE_TTI_SECONDS),--cache-tti-seconds=$(CACHE_TTI_SECONDS)) \ + $(if $(LOG_LEVEL),--log-level=$(LOG_LEVEL)) \ + $(if $(TRACING),--tracing) \ + $(if $(OTLP_AGENT_HOST),--otlp-agent-host=$(OTLP_AGENT_HOST)) \ + $(if $(OTLP_AGENT_PORT),--otlp-agent-port=$(OTLP_AGENT_PORT)) \ + $(if $(OTLP_TRACING_SERVICE_NAME),--otlp-tracing-service-name=$(OTLP_TRACING_SERVICE_NAME)) diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000000..bafe553c20 --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,8 @@ +pometry-storage-private +.dockerignore +target/ +.git/ +.env +.idea/ +.vscode/ +Dockerfile* diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile new file mode 100644 index 0000000000..b75d699bfd --- /dev/null +++ b/docker/base/Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.12.4-slim + +# Install packages & python base +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + python3 \ + protobuf-compiler \ + curl \ + g++ \ + git \ + libssl-dev \ + patchelf && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create a virtual environment +RUN python3 -m venv /opt/venv +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +# Install Rustup +RUN curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y +ENV PATH="/root/.cargo/bin:${PATH}" +RUN rustup toolchain install 1.82.0 && rustup default 1.82.0 +RUN cargo install --locked maturin + +WORKDIR /home/raphtory_server + +ENTRYPOINT [ "/bin/sh"] diff --git a/docker/dockerfile b/docker/dockerfile new file mode 100644 index 0000000000..4d40664cc2 --- /dev/null +++ b/docker/dockerfile @@ -0,0 +1,27 @@ +#THIS SHOULD BE RUN FROM THE MAIN RAPHTORY DIR VIA MAKE +# Stage 1: Build +ARG BASE_IMAGE +FROM ${BASE_IMAGE} AS build + +WORKDIR /home/raphtory_server + +# Install custom raphtory and then delete the files +COPY . /home/raphtory_server/raphtory +RUN cd raphtory && rm -rf target && rm -rf pometry-storage-private +RUN cd raphtory/python && maturin build -r +RUN cd raphtory && pip install $(ls target/wheels/*.whl | head -n 1) +RUN rm -rf raphtory + +RUN pip install python-dotenv + +# # Stage 2: Final +FROM python:3.12.4-slim + +# Copy the virtual environment from the build stage +COPY --from=build /opt/venv /opt/venv +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +COPY docker/server.py /home/raphtory_server/server.py + +ENTRYPOINT ["python", "/home/raphtory_server/server.py"] diff --git a/docker/server.py b/docker/server.py new file mode 100644 index 0000000000..ec0865d53d --- /dev/null +++ b/docker/server.py @@ -0,0 +1,75 @@ +from raphtory import graphql +from dotenv import load_dotenv +import argparse + +# Load the .env file +load_dotenv() + +parser = argparse.ArgumentParser(description="For passing the working_dir") +parser.add_argument( + "--working-dir", + type=str, + default="graphs", + help="Path for the working directory of the raphtory server, defaults to 'graphs/'", +) +parser.add_argument( + "--port", + type=int, + default=1736, + help="Graphql server port, defaults to 1736", +) +parser.add_argument( + "--log-level", + type=str, + default="info", + help="Log level for the server, defaults to info", +) +parser.add_argument( + "--tracing", + type=bool, + default=False, + help="If tracing should be enabled or not, defaults to False", +) +parser.add_argument( + "--otlp-agent-host", + type=str, + default="localhost", + help="The address of the open telemetry collector, defaults to localhost", +) +parser.add_argument( + "--otlp-agent-port", + type=str, + default="4317", + help="The port of the open telemetry collector, default to 4317", +) +parser.add_argument( + "--otlp-tracing-service-name", + type=str, + default="Raphtory", + help="The name this service will be known by for open telemetry, default to Raphtory", +) +parser.add_argument( + "--cache-capacity", + type=int, + default=30, + help="The maximum amount of graphs to keep in memory at any given time, defaults to 30", +) +parser.add_argument( + "--cache-tti-seconds", + type=int, + default=900, + help="The amount of time a graph will be kept in memory before being dropped, defaults to 900 seconds", +) +args = parser.parse_args() + +server = graphql.GraphServer( + work_dir=args.working_dir, + tracing=args.tracing, + log_level=args.log_level, + otlp_agent_host=args.otlp_agent_host, + otlp_agent_port=args.otlp_agent_port, + otlp_tracing_service_name=args.otlp_tracing_service_name, + cache_capacity=args.cache_capacity, + cache_tti_seconds=args.cache_tti_seconds +) +server.run(port=args.port) diff --git a/raphtory-graphql/Cargo.toml b/raphtory-graphql/Cargo.toml index dd8f44638a..4259396f72 100644 --- a/raphtory-graphql/Cargo.toml +++ b/raphtory-graphql/Cargo.toml @@ -54,6 +54,7 @@ pyo3 = { workspace = true, optional = true } crossbeam-channel = { workspace = true } minijinja = { workspace = true } zip = { workspace = true } +clap = { version = "4.0", features = ["derive"] } [dev-dependencies] tempfile = { workspace = true } diff --git a/raphtory-graphql/resources/index.html b/raphtory-graphql/resources/index.html index ba1fcdaabe..a8a2146ec8 100644 --- a/raphtory-graphql/resources/index.html +++ b/raphtory-graphql/resources/index.html @@ -856,4 +856,4 @@
- + \ No newline at end of file diff --git a/raphtory-graphql/src/config/app_config.rs b/raphtory-graphql/src/config/app_config.rs index 8244c5857e..80e4f212e2 100644 --- a/raphtory-graphql/src/config/app_config.rs +++ b/raphtory-graphql/src/config/app_config.rs @@ -5,7 +5,7 @@ use config::{Config, ConfigError, File}; use serde::Deserialize; use std::path::PathBuf; -#[derive(Debug, Deserialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, PartialEq, Clone, serde::Serialize)] pub struct AppConfig { pub logging: LoggingConfig, pub cache: CacheConfig, diff --git a/raphtory-graphql/src/config/cache_config.rs b/raphtory-graphql/src/config/cache_config.rs index eeb01afc06..eb9320a605 100644 --- a/raphtory-graphql/src/config/cache_config.rs +++ b/raphtory-graphql/src/config/cache_config.rs @@ -1,5 +1,9 @@ use serde::Deserialize; -#[derive(Debug, Deserialize, PartialEq, Clone)] + +pub const DEFAULT_CAPACITY: u64 = 30; +pub const DEFAULT_TTI_SECONDS: u64 = 900; + +#[derive(Debug, Deserialize, PartialEq, Clone, serde::Serialize)] pub struct CacheConfig { pub capacity: u64, pub tti_seconds: u64, @@ -8,8 +12,8 @@ pub struct CacheConfig { impl Default for CacheConfig { fn default() -> Self { Self { - capacity: 30, - tti_seconds: 900, + capacity: DEFAULT_CAPACITY, + tti_seconds: DEFAULT_TTI_SECONDS, } } } diff --git a/raphtory-graphql/src/config/log_config.rs b/raphtory-graphql/src/config/log_config.rs index 1dec9139b2..933a44ca42 100644 --- a/raphtory-graphql/src/config/log_config.rs +++ b/raphtory-graphql/src/config/log_config.rs @@ -1,7 +1,9 @@ use serde::Deserialize; use tracing_subscriber::EnvFilter; -#[derive(Debug, Deserialize, PartialEq, Clone)] +pub const DEFAULT_LOG_LEVEL: &'static str = "INFO"; + +#[derive(Debug, Deserialize, PartialEq, Clone, serde::Serialize)] pub struct LoggingConfig { pub log_level: String, } @@ -15,7 +17,7 @@ impl LoggingConfig { impl Default for LoggingConfig { fn default() -> Self { Self { - log_level: "INFO".to_string(), + log_level: DEFAULT_LOG_LEVEL.to_owned(), } } } diff --git a/raphtory-graphql/src/config/otlp_config.rs b/raphtory-graphql/src/config/otlp_config.rs index 22af1d81fd..8e6a162763 100644 --- a/raphtory-graphql/src/config/otlp_config.rs +++ b/raphtory-graphql/src/config/otlp_config.rs @@ -9,23 +9,30 @@ use serde::Deserialize; use std::time::Duration; use tracing::{error, info}; -#[derive(Clone, Deserialize, Debug, PartialEq)] +pub const DEFAULT_TRACING_ENABLED: bool = false; +pub const DEFAULT_OTLP_AGENT_HOST: &'static str = "http://localhost"; +pub const DEFAULT_OTLP_AGENT_PORT: &'static str = "4317"; +pub const DEFAULT_OTLP_TRACING_SERVICE_NAME: &'static str = "Raphtory"; + +#[derive(Clone, Deserialize, Debug, PartialEq, serde::Serialize)] pub struct TracingConfig { pub tracing_enabled: bool, pub otlp_agent_host: String, pub otlp_agent_port: String, pub otlp_tracing_service_name: String, } + impl Default for TracingConfig { fn default() -> Self { Self { - tracing_enabled: false, - otlp_agent_host: "http://localhost".to_string(), - otlp_agent_port: "4317".to_string(), - otlp_tracing_service_name: "Raphtory".to_string(), + tracing_enabled: DEFAULT_TRACING_ENABLED, + otlp_agent_host: DEFAULT_OTLP_AGENT_HOST.to_owned(), + otlp_agent_port: DEFAULT_OTLP_AGENT_PORT.to_owned(), + otlp_tracing_service_name: DEFAULT_OTLP_TRACING_SERVICE_NAME.to_owned(), } } } + impl TracingConfig { pub fn tracer_provider(&self) -> Option { if self.tracing_enabled { diff --git a/raphtory-graphql/src/data.rs b/raphtory-graphql/src/data.rs index 7640f954fd..8d6c907e37 100644 --- a/raphtory-graphql/src/data.rs +++ b/raphtory-graphql/src/data.rs @@ -33,7 +33,7 @@ pub struct EmbeddingConf { #[derive(Clone)] pub struct Data { - work_dir: PathBuf, + pub(crate) work_dir: PathBuf, cache: Cache, pub(crate) index: bool, pub(crate) embedding_conf: Option, diff --git a/raphtory-graphql/src/main.rs b/raphtory-graphql/src/main.rs index 656002eaae..c12b29b383 100644 --- a/raphtory-graphql/src/main.rs +++ b/raphtory-graphql/src/main.rs @@ -1,22 +1,69 @@ -use raphtory_graphql::{config::app_config::AppConfigBuilder, server::DEFAULT_PORT, GraphServer}; -use std::{ - env, - path::{Path, PathBuf}, +use clap::{command, Parser}; +use raphtory_graphql::{ + config::{ + app_config::AppConfigBuilder, + cache_config::{DEFAULT_CAPACITY, DEFAULT_TTI_SECONDS}, + log_config::DEFAULT_LOG_LEVEL, + otlp_config::{ + DEFAULT_OTLP_AGENT_HOST, DEFAULT_OTLP_AGENT_PORT, DEFAULT_OTLP_TRACING_SERVICE_NAME, + DEFAULT_TRACING_ENABLED, + }, + }, + server::DEFAULT_PORT, + GraphServer, }; +use std::path::PathBuf; use tokio::io::Result as IoResult; +#[derive(Parser)] +#[command(about = "Run the GraphServer with specified configurations")] +struct Args { + #[arg(long, default_value = "graphs")] + working_dir: PathBuf, + + #[arg(long, default_value_t = DEFAULT_PORT)] + port: u16, + + #[arg(long, default_value_t = DEFAULT_CAPACITY)] + cache_capacity: u64, + + #[arg(long, default_value_t = DEFAULT_TTI_SECONDS)] + cache_tti_seconds: u64, + + #[arg(long, default_value = DEFAULT_LOG_LEVEL)] + log_level: String, + + #[arg(long, default_value_t = DEFAULT_TRACING_ENABLED)] + tracing: bool, + + #[arg(long, default_value = DEFAULT_OTLP_AGENT_HOST)] + otlp_agent_host: String, + + #[arg(long, default_value = DEFAULT_OTLP_AGENT_PORT)] + otlp_agent_port: String, + + #[arg(long, default_value = DEFAULT_OTLP_TRACING_SERVICE_NAME)] + otlp_tracing_service_name: String, +} + #[tokio::main] async fn main() -> IoResult<()> { - let default_path = Path::new("."); - let port: u16 = env::var("PORT") - .map(|port| port.parse().unwrap()) - .unwrap_or(DEFAULT_PORT); - let work_dir = env::var("GRAPH_DIRECTORY").unwrap_or(default_path.display().to_string()); - let work_dir = PathBuf::from(&work_dir); - let app_config = Some(AppConfigBuilder::new().with_tracing(true).build()); - GraphServer::new(work_dir, app_config, None)? - .run_with_port(port) - .await?; + let args = Args::parse(); + + let app_config = Some( + AppConfigBuilder::new() + .with_cache_capacity(args.cache_capacity) + .with_cache_tti_seconds(args.cache_tti_seconds) + .with_log_level(args.log_level) + .with_tracing(args.tracing) + .with_otlp_agent_host(args.otlp_agent_host) + .with_otlp_agent_port(args.otlp_agent_port) + .with_otlp_tracing_service_name(args.otlp_tracing_service_name) + .build(), + ); + GraphServer::new(args.working_dir, app_config, None)? + .run_with_port(args.port) + .await?; Ok(()) } diff --git a/raphtory-graphql/src/server.rs b/raphtory-graphql/src/server.rs index 5d109eb087..bc6515cabd 100644 --- a/raphtory-graphql/src/server.rs +++ b/raphtory-graphql/src/server.rs @@ -22,6 +22,7 @@ use poem::{ EndpointExt, Route, Server, }; use raphtory::vectors::{template::DocumentTemplate, EmbeddingFunction}; +use serde_json::json; use std::{ fs, path::{Path, PathBuf}, @@ -177,7 +178,8 @@ impl GraphServer { pub async fn start_with_port(self, port: u16) -> IoResult { self.data.vectorise_all_graphs_that_are_not().await?; - let config = &self.config; + let work_dir = self.data.work_dir.clone(); + let config = self.config.clone(); let filter = config.logging.get_log_env(); let tracer_name = config.tracing.otlp_tracing_service_name.clone(); let tp = config.tracing.tracer_provider(); @@ -208,6 +210,14 @@ impl GraphServer { let (signal_sender, signal_receiver) = mpsc::channel(1); info!("Playground live at: http://0.0.0.0:{port}"); + debug!( + "Server configurations: {}", + json!({ + "config": config, + "work_dir": work_dir + }) + ); + let server_task = Server::new(TcpListener::bind(format!("0.0.0.0:{port}"))) .run_with_graceful_shutdown(app, server_termination(signal_receiver, tp), None); let server_result = tokio::spawn(server_task);