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