surrealdb_server/lib.rs
1//! Library entrypoints for embedding SurrealDB server inside another Rust application.
2//! Exposes the same init() used by the `surreal` binary so external apps can
3//! start SurrealDB within their own `main()`.
4//!
5//! <section class="warning">
6//! <h3>Unstable!</h3>
7//! This crate is <b>SurrealDB internal API</b>. It does not adhere to SemVer and its API is
8//! free to change and break code even between patch versions. If you are looking for a stable
9//! interface to the SurrealDB library please have a look at
10//! <a href="https://crates.io/crates/surrealdb">the Rust SDK</a>.
11//! </section>
12
13// Temporarily allow deprecated items until version 3.0 for backward compatibility
14#![allow(deprecated)]
15#![deny(clippy::mem_forget)]
16
17#[macro_use]
18extern crate tracing;
19
20mod cli;
21mod cnf;
22mod dbs;
23mod env;
24#[cfg(feature = "graphql")]
25mod gql;
26/// Make `ntw` public so embedders can access RouterFactory and related networking definitions
27/// when running SurrealDB as a library.
28pub mod ntw;
29/// Make `rpc` public so embedders can access RpcState and related router definitions
30/// when running SurrealDB as a library.
31pub mod rpc;
32mod telemetry;
33
34use std::future::Future;
35use std::process::ExitCode;
36
37pub use cli::{Config, ConfigCheck, ConfigCheckRequirements};
38/// Re-export `RouterFactory` for convenience so embedders can `use surreal::RouterFactory`.
39#[doc(inline)]
40pub use ntw::RouterFactory;
41/// Re-export `RpcState` for convenience so embedders can `use surreal::RpcState`.
42#[doc(inline)]
43pub use rpc::RpcState;
44#[doc(inline)]
45pub use surrealdb as sdk;
46/// Re-export `core` for convenience so embedders can `use surreal::core::...`.
47#[doc(inline)]
48pub use surrealdb_core as core;
49use surrealdb_core::buc::BucketStoreProvider;
50use surrealdb_core::kvs::TransactionBuilderFactory;
51
52// Re-export the core crate in the same path used across internal modules
53// so that `crate::core::...` keeps working when used as a library target.
54
55/// Initialize SurrealDB CLI/server with the same behavior as the `surreal` binary.
56/// This spins up a Tokio runtime with a larger stack size and then runs the CLI
57/// entrypoint (which starts the server when the `start` subcommand is used).
58///
59/// # Parameters
60/// - `composer`: A composer implementing the required traits for dependency injection.
61///
62/// # Generic parameters
63/// - `C`: A composer type that implements:
64/// - `TransactionBuilderFactory` (selects/validates the datastore backend)
65/// - `RouterFactory` (constructs the HTTP router)
66/// - `ConfigCheck` (validates configuration before initialization)
67pub fn init<C: TransactionBuilderFactory + RouterFactory + ConfigCheck + BucketStoreProvider>(
68 composer: C,
69) -> ExitCode {
70 with_enough_stack(cli::init::<C>(composer))
71}
72
73/// Rust's default thread stack size of 2MiB doesn't allow sufficient recursion depth
74/// for SurrealDB's query parser and execution engine. This function creates a Tokio
75/// runtime with a larger stack size configured via `cnf::RUNTIME_STACK_SIZE`.
76fn with_enough_stack(fut: impl Future<Output = ExitCode> + Send) -> ExitCode {
77 // Start a Tokio runtime with custom configuration
78 let runtime = tokio::runtime::Builder::new_multi_thread()
79 .enable_all()
80 .max_blocking_threads(*cnf::RUNTIME_MAX_BLOCKING_THREADS)
81 .worker_threads(*cnf::RUNTIME_WORKER_THREADS)
82 .thread_stack_size(*cnf::RUNTIME_STACK_SIZE)
83 .thread_name("surrealdb-worker")
84 // When a thread is parked, ensure that local memory
85 // tracking is flushed to the global tracking counter.
86 .on_thread_park(|| core::mem::ALLOC.flush_local_allocations())
87 // When a thread is shutdown, ensure that local memory
88 // tracking is flushed to the global tracking counter.
89 .on_thread_stop(|| core::mem::ALLOC.flush_local_allocations())
90 // Build the runtime
91 .build();
92 // Check the success of the runtime creation
93 match runtime {
94 Ok(r) => r.block_on(fut),
95 Err(e) => {
96 // The runtime creation failed (e.g. insufficient system resources)
97 error!("Failed to build runtime: {e}");
98 ExitCode::FAILURE
99 }
100 }
101}