Skip to main content
Glama

Convex MCP server

Official
by get-convex
transaction_id_generator.rs3.08 kB
use std::time::SystemTime; use common::{ document::InternalId, runtime::Runtime, }; use rand::{ Rng, RngCore, SeedableRng, }; use rand_chacha::ChaCha12Rng; use value::{ DeveloperDocumentId, ResolvedDocumentId, TableNumber, TabletIdAndTableNumber, }; /// A production ID generator scoped to a single transaction. /// /// This creates InternalIds with 14 bytes of randomness followed by the day in /// 2 bytes. /// /// The time is pinned on construction, so only use for a single transaction! pub struct TransactionIdGenerator { rng: ChaCha12Rng, day_bytes: [u8; 2], } impl TransactionIdGenerator { pub fn new<RT: Runtime>(runtime: &RT) -> anyhow::Result<Self> { let rng_seed = runtime.rng().random(); let rng = ChaCha12Rng::from_seed(rng_seed); // Get the current day as 2 bytes. let duration = runtime .system_time() .duration_since(SystemTime::UNIX_EPOCH)?; let days = duration.as_secs() / 86400; let day_bytes = days.to_be_bytes(); // First 6 bytes should always be 0 (this only works until 2149). anyhow::ensure!(day_bytes[..6] == [0u8; 6]); Ok(Self { rng, day_bytes: day_bytes[6..].try_into()?, }) } pub fn generate_internal(&mut self) -> InternalId { let mut id_bytes = [0u8; 16]; self.rng.fill_bytes(&mut id_bytes[..14]); id_bytes[14..].clone_from_slice(&self.day_bytes); InternalId(id_bytes) } pub fn generate(&mut self, table_number: TableNumber) -> DeveloperDocumentId { DeveloperDocumentId::new(table_number, self.generate_internal()) } pub fn generate_resolved( &mut self, tablet_id_and_number: TabletIdAndTableNumber, ) -> ResolvedDocumentId { ResolvedDocumentId::new( tablet_id_and_number.tablet_id, DeveloperDocumentId::new(tablet_id_and_number.table_number, self.generate_internal()), ) } } #[cfg(test)] mod tests { use std::time::SystemTime; use common::runtime::Runtime; use runtime::testing::TestDriver; use value::TableNumber; use crate::transaction_id_generator::TransactionIdGenerator; // Make sure that our production generated IDs really do contain the day in the // last two bytes. #[test] fn generated_ids_include_day() -> anyhow::Result<()> { let td = TestDriver::new(); let table = TableNumber::MIN; let mut id_generator = TransactionIdGenerator::new(&td.rt())?; let id = id_generator.generate(table); let bytes = &id.internal_id()[..]; let mut day_bytes = [0u8; 8]; day_bytes[6..].copy_from_slice(&bytes[14..]); let day_from_id = u64::from_be_bytes(day_bytes); let duration = td .rt() .system_time() .duration_since(SystemTime::UNIX_EPOCH)?; let day_from_system_time = (duration.as_secs()) / 86400; assert_eq!(day_from_id, day_from_system_time); Ok(()) } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/get-convex/convex-backend'

If you have feedback or need assistance with the MCP directory API, please join our Discord server