Skip to main content

rivetkit_core/
lib.rs

1#[cfg(all(feature = "native-runtime", feature = "wasm-runtime"))]
2compile_error!(
3	"`native-runtime` and `wasm-runtime` are mutually exclusive. Enable exactly one rivetkit-core runtime."
4);
5
6pub mod actor;
7#[cfg(feature = "native-runtime")]
8mod development_process;
9#[cfg(feature = "native-runtime")]
10pub mod engine_process;
11pub mod error;
12pub mod inspector;
13pub mod inspector_bundle;
14pub mod metrics;
15pub mod registry;
16pub mod runtime;
17pub(crate) mod serde_metrics;
18pub mod serverless;
19#[cfg(feature = "native-runtime")]
20pub mod serverless_http;
21#[cfg(feature = "native-runtime")]
22mod services_process;
23pub mod telemetry;
24#[doc(hidden)]
25pub use telemetry::{
26	ActorInvocationSpanContext, ActorInvocationTelemetry, ActorInvocationTraceContext,
27	IncomingTraceContext, OutboundCallInvocation, WorkflowRunInvocation, WorkflowRunOutcome,
28	WorkflowStepOutcome, WorkflowStepSpan,
29};
30#[cfg(any(test, feature = "test-support"))]
31pub mod testing;
32#[cfg(not(target_arch = "wasm32"))]
33pub mod tokio_runtime_metrics;
34pub(crate) mod time {
35	use std::fmt;
36	use std::future::Future;
37	use std::time::Duration;
38
39	#[cfg(target_arch = "wasm32")]
40	use futures::FutureExt;
41	#[cfg(target_arch = "wasm32")]
42	use wasm_bindgen::{JsCast, JsValue};
43	#[cfg(target_arch = "wasm32")]
44	use wasm_bindgen_futures::JsFuture;
45
46	#[cfg(not(target_arch = "wasm32"))]
47	pub use std::time::{Instant, SystemTime, UNIX_EPOCH};
48	#[cfg(target_arch = "wasm32")]
49	pub use web_time::{Instant, SystemTime, UNIX_EPOCH};
50
51	#[derive(Debug, Clone, Copy)]
52	pub struct TimeoutError;
53
54	impl fmt::Display for TimeoutError {
55		fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56			f.write_str("operation timed out")
57		}
58	}
59
60	impl std::error::Error for TimeoutError {}
61
62	#[cfg(not(target_arch = "wasm32"))]
63	pub fn tokio_deadline(deadline: Instant) -> tokio::time::Instant {
64		deadline.into()
65	}
66
67	#[cfg(target_arch = "wasm32")]
68	pub async fn sleep(duration: Duration) {
69		let delay_ms = duration.as_millis().min(u32::MAX as u128) as f64;
70		let promise = js_sys::Promise::new(&mut |resolve, _reject| {
71			let global = js_sys::global();
72			let set_timeout = js_sys::Reflect::get(&global, &JsValue::from_str("setTimeout"))
73				.ok()
74				.and_then(|value| value.dyn_into::<js_sys::Function>().ok());
75
76			if let Some(set_timeout) = set_timeout {
77				let _ = set_timeout.call2(&global, &resolve, &JsValue::from_f64(delay_ms));
78			} else {
79				let _ = resolve.call0(&JsValue::UNDEFINED);
80			}
81		});
82
83		let _ = JsFuture::from(promise).await;
84	}
85
86	#[cfg(not(target_arch = "wasm32"))]
87	pub async fn sleep(duration: Duration) {
88		tokio::time::sleep(duration).await;
89	}
90
91	#[cfg(not(target_arch = "wasm32"))]
92	pub async fn sleep_until(deadline: Instant) {
93		tokio::time::sleep_until(tokio_deadline(deadline)).await;
94	}
95
96	#[cfg(target_arch = "wasm32")]
97	pub async fn sleep_until(deadline: Instant) {
98		let remaining = deadline
99			.checked_duration_since(Instant::now())
100			.unwrap_or(Duration::ZERO);
101		sleep(remaining).await;
102	}
103
104	#[cfg(not(target_arch = "wasm32"))]
105	pub async fn timeout<F>(duration: Duration, future: F) -> Result<F::Output, TimeoutError>
106	where
107		F: Future,
108	{
109		tokio::time::timeout(duration, future)
110			.await
111			.map_err(|_| TimeoutError)
112	}
113
114	#[cfg(target_arch = "wasm32")]
115	pub async fn timeout<F>(duration: Duration, future: F) -> Result<F::Output, TimeoutError>
116	where
117		F: Future,
118	{
119		futures::pin_mut!(future);
120		let timer = sleep(duration);
121		futures::pin_mut!(timer);
122
123		futures::select! {
124			result = future.fuse() => Ok(result),
125			_ = timer.fuse() => Err(TimeoutError),
126		}
127	}
128}
129pub mod types;
130pub mod websocket;
131pub use actor::{kv, sqlite};
132
133pub use actor::action::ActionDispatchError;
134pub use actor::config::{
135	ActionDefinition, ActorConfig, ActorConfigInput, ActorConfigOverrides, ActorTracingConfig,
136	CanHibernateWebSocket, SqliteProfilingConfig, SqliteProfilingConfigInput,
137};
138pub use actor::connection::ConnHandle;
139pub use actor::context::{
140	ActorContext, ActorKv, ActorWorkRegion, KeepAwakeRegion, WebSocketCallbackRegion,
141};
142pub use actor::factory::{ActorEntryFn, ActorFactory};
143pub use actor::lifecycle_hooks::{ActorEvents, ActorStart, Reply};
144pub use actor::messages::{
145	ActorEvent, ActorHttpResponse, QueueSendResult, QueueSendStatus, Request, Response,
146	SerializeStateReason, StateDelta, StreamingResponse, WorkflowKvWrite,
147};
148pub use actor::queue::{
149	CompletableQueueMessage, EnqueueAndWaitOpts, QueueMessage, QueueNextBatchOpts, QueueNextOpts,
150	QueueTryNextBatchOpts, QueueTryNextOpts, QueueWaitOpts,
151};
152pub use actor::sqlite::{
153	BindParam, ColumnValue, ExecResult, ExecuteResult, QueryResult, SqliteBackend,
154	SqliteBatchStatement, SqliteDb, SqliteTransaction,
155};
156pub use actor::state::{ActorStateTransaction, RequestSaveOpts};
157pub use actor::task::{
158	ActionDispatchResult, ActorTask, DispatchCommand, HttpDispatchResult, LifecycleCommand,
159	LifecycleEvent, LifecycleState,
160};
161pub use actor::task_types::ShutdownKind;
162pub use actor::work_registry::{ActorWorkKind, ActorWorkPolicy};
163pub use error::ActorLifecycle;
164pub use inspector::{Inspector, InspectorSnapshot};
165pub use registry::{CoreRegistry, EngineSpawnMode, RuntimeMode, ServeConfig};
166pub use rivet_envoy_client::config::{
167	HTTP_BODY_MAX_CHUNK_SIZE, HTTP_BODY_STREAM_CHANNEL_CAPACITY, HttpRequestBodyStream,
168	ResponseChunk,
169};
170pub use runtime::{RuntimeBoxFuture, RuntimeSpawner, boxed_runtime_future};
171pub use serverless::{CoreServerlessRuntime, ServerlessRequest, ServerlessResponse};
172pub use types::{
173	ActorKey, ActorKeySegment, ConnId, ListOpts, SaveStateOpts, WsMessage, format_actor_key,
174};
175pub use websocket::WebSocket;