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