1use serde::Serialize;
2
3use crate::error::{Result, SyncularError};
4use crate::store::{
5 BLOB_UPLOAD_STALE_TIMEOUT_MS, MAX_BLOB_UPLOAD_RETRIES, MAX_SYNC_RETRIES,
6 SQLITE_BUSY_TIMEOUT_MS, SYNC_SENDING_TIMEOUT_MS,
7};
8
9pub const DEFAULT_WORKER_COMMAND_QUEUE_CAPACITY: usize = 1024;
10pub const DEFAULT_WORKER_EVENT_QUEUE_CAPACITY: usize = 1024;
11pub const DEFAULT_NATIVE_EVENT_STREAM_CAPACITY: usize = 256;
12pub const DEFAULT_NATIVE_RECENT_EVENT_LIMIT: usize = 100;
13pub const DEFAULT_READONLY_QUERY_STATEMENT_CACHE_CAPACITY: usize = 64;
14
15pub const DEFAULT_PULL_LIMIT_COMMITS: i64 = 1000;
16pub const DEFAULT_PULL_LIMIT_SNAPSHOT_ROWS: i64 = 50_000;
17pub const DEFAULT_PULL_MAX_SNAPSHOT_PAGES: i64 = 10;
18pub const DEFAULT_OUTBOX_PUSH_BATCH_LIMIT: i64 = 20;
19pub const DEFAULT_ADAPTIVE_OUTBOX_PUSH_BATCH_LIMIT: i64 = MAX_OUTBOX_PUSH_BATCH_LIMIT;
20pub const DEFAULT_ADAPTIVE_OUTBOX_PUSH_THRESHOLD: i64 = 100;
21pub const MAX_OUTBOX_PUSH_BATCH_LIMIT: i64 = 1000;
22pub const DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS: usize = 10_000;
23pub const DEFAULT_BLOB_UPLOAD_BATCH_LIMIT: i64 = 10;
24
25pub const DEFAULT_CRDT_STATE_VECTOR_HINT_LIMIT: i64 = 256;
26pub const DEFAULT_CRDT_UPDATE_QUEUE_CAPACITY: i64 = 1024;
27pub const DEFAULT_CRDT_UPDATE_LOG_LIMIT: i64 = 100;
28
29pub const DEFAULT_YJS_FLUSH_WINDOW_MS: u64 = 12;
30
31pub const MAX_SUBSCRIPTIONS_PER_CLIENT: usize = 256;
32pub const MAX_SCOPE_KEYS_PER_SUBSCRIPTION: usize = 16;
33pub const MAX_SCOPE_VALUES_PER_SUBSCRIPTION: usize = 4096;
34pub const MAX_SCOPE_VALUES_PER_CLIENT: usize = 16_384;
35pub const MAX_SUBSCRIPTION_PARAMS_PER_SUBSCRIPTION: usize = 32;
36pub const MAX_MUTATION_OPERATION_JSON_BYTES: usize = 1024 * 1024;
37pub const MAX_MUTATION_LOCAL_ROW_JSON_BYTES: usize = 1024 * 1024;
38pub const MAX_MUTATION_BATCH_JSON_BYTES: usize = 4 * 1024 * 1024;
39pub const MAX_OUTBOX_OPERATIONS_JSON_BYTES: usize = 4 * 1024 * 1024;
40pub const MAX_BLOB_PAYLOAD_BYTES: i64 = 64 * 1024 * 1024;
41pub const MAX_CRDT_REQUEST_JSON_BYTES: usize = 4 * 1024 * 1024;
42pub const MAX_CRDT_UPDATE_BASE64_BYTES: usize = 1024 * 1024;
43pub const MAX_CRDT_STATE_BASE64_BYTES: usize = 4 * 1024 * 1024;
44pub const MAX_CRDT_STATE_VECTOR_BASE64_BYTES: usize = 64 * 1024;
45pub const MAX_CRDT_TEXT_BYTES: usize = 1024 * 1024;
46pub const MAX_NATIVE_DIAGNOSTIC_EVENT_PAYLOAD_JSON_BYTES: usize = 16 * 1024;
47pub const MAX_SNAPSHOT_CHUNK_COMPRESSED_BYTES: i64 = 64 * 1024 * 1024;
48pub const MAX_SNAPSHOT_CHUNK_DECOMPRESSED_BYTES: usize = 256 * 1024 * 1024;
49pub const MAX_SNAPSHOT_ARTIFACT_COMPRESSED_BYTES: i64 = 256 * 1024 * 1024;
50pub const MAX_SNAPSHOT_ARTIFACT_DECOMPRESSED_BYTES: usize = 512 * 1024 * 1024;
51pub const MAX_REALTIME_SYNC_PACK_BYTES: usize = 16 * 1024 * 1024;
52pub const MAX_WEBSOCKET_TEXT_FRAME_BYTES: usize = 8 * 1024 * 1024;
53
54#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
55#[serde(rename_all = "camelCase")]
56pub struct RuntimeLimits {
57 pub worker_command_queue_capacity: usize,
58 pub worker_event_queue_capacity: usize,
59 pub native_default_event_stream_capacity: usize,
60 pub native_recent_event_limit: usize,
61 pub readonly_query_statement_cache_capacity: usize,
62 pub pull_limit_commits: i64,
63 pub pull_limit_snapshot_rows: i64,
64 pub pull_max_snapshot_pages: i64,
65 pub outbox_push_batch_limit: i64,
66 pub adaptive_outbox_push_batch_limit: i64,
67 pub adaptive_outbox_push_threshold: i64,
68 pub max_unresolved_outbox_commits: usize,
69 pub max_sync_retries: i32,
70 pub sync_sending_timeout_ms: i64,
71 pub max_blob_upload_retries: i32,
72 pub blob_upload_stale_timeout_ms: i64,
73 pub blob_upload_batch_limit: i64,
74 pub sqlite_busy_timeout_ms: i32,
75 pub crdt_state_vector_hint_limit: i64,
76 pub crdt_update_queue_capacity: i64,
77 pub crdt_update_log_default_limit: i64,
78 pub yjs_flush_window_ms: u64,
79 pub max_subscriptions_per_client: usize,
80 pub max_scope_keys_per_subscription: usize,
81 pub max_scope_values_per_subscription: usize,
82 pub max_scope_values_per_client: usize,
83 pub max_subscription_params_per_subscription: usize,
84 pub max_mutation_operation_json_bytes: usize,
85 pub max_mutation_local_row_json_bytes: usize,
86 pub max_mutation_batch_json_bytes: usize,
87 pub max_outbox_operations_json_bytes: usize,
88 pub max_blob_payload_bytes: i64,
89 pub max_crdt_request_json_bytes: usize,
90 pub max_crdt_update_base64_bytes: usize,
91 pub max_crdt_state_base64_bytes: usize,
92 pub max_crdt_state_vector_base64_bytes: usize,
93 pub max_crdt_text_bytes: usize,
94 pub max_native_diagnostic_event_payload_json_bytes: usize,
95 pub max_snapshot_chunk_compressed_bytes: i64,
96 pub max_snapshot_chunk_decompressed_bytes: usize,
97 pub max_snapshot_artifact_compressed_bytes: i64,
98 pub max_snapshot_artifact_decompressed_bytes: usize,
99 pub max_realtime_sync_pack_bytes: usize,
100 pub max_websocket_text_frame_bytes: usize,
101}
102
103pub fn runtime_default_limits() -> RuntimeLimits {
104 RuntimeLimits {
105 worker_command_queue_capacity: DEFAULT_WORKER_COMMAND_QUEUE_CAPACITY,
106 worker_event_queue_capacity: DEFAULT_WORKER_EVENT_QUEUE_CAPACITY,
107 native_default_event_stream_capacity: DEFAULT_NATIVE_EVENT_STREAM_CAPACITY,
108 native_recent_event_limit: DEFAULT_NATIVE_RECENT_EVENT_LIMIT,
109 readonly_query_statement_cache_capacity: DEFAULT_READONLY_QUERY_STATEMENT_CACHE_CAPACITY,
110 pull_limit_commits: DEFAULT_PULL_LIMIT_COMMITS,
111 pull_limit_snapshot_rows: DEFAULT_PULL_LIMIT_SNAPSHOT_ROWS,
112 pull_max_snapshot_pages: DEFAULT_PULL_MAX_SNAPSHOT_PAGES,
113 outbox_push_batch_limit: DEFAULT_OUTBOX_PUSH_BATCH_LIMIT,
114 adaptive_outbox_push_batch_limit: DEFAULT_ADAPTIVE_OUTBOX_PUSH_BATCH_LIMIT,
115 adaptive_outbox_push_threshold: DEFAULT_ADAPTIVE_OUTBOX_PUSH_THRESHOLD,
116 max_unresolved_outbox_commits: DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS,
117 max_sync_retries: MAX_SYNC_RETRIES,
118 sync_sending_timeout_ms: SYNC_SENDING_TIMEOUT_MS,
119 max_blob_upload_retries: MAX_BLOB_UPLOAD_RETRIES,
120 blob_upload_stale_timeout_ms: BLOB_UPLOAD_STALE_TIMEOUT_MS,
121 blob_upload_batch_limit: DEFAULT_BLOB_UPLOAD_BATCH_LIMIT,
122 sqlite_busy_timeout_ms: SQLITE_BUSY_TIMEOUT_MS,
123 crdt_state_vector_hint_limit: DEFAULT_CRDT_STATE_VECTOR_HINT_LIMIT,
124 crdt_update_queue_capacity: DEFAULT_CRDT_UPDATE_QUEUE_CAPACITY,
125 crdt_update_log_default_limit: DEFAULT_CRDT_UPDATE_LOG_LIMIT,
126 yjs_flush_window_ms: DEFAULT_YJS_FLUSH_WINDOW_MS,
127 max_subscriptions_per_client: MAX_SUBSCRIPTIONS_PER_CLIENT,
128 max_scope_keys_per_subscription: MAX_SCOPE_KEYS_PER_SUBSCRIPTION,
129 max_scope_values_per_subscription: MAX_SCOPE_VALUES_PER_SUBSCRIPTION,
130 max_scope_values_per_client: MAX_SCOPE_VALUES_PER_CLIENT,
131 max_subscription_params_per_subscription: MAX_SUBSCRIPTION_PARAMS_PER_SUBSCRIPTION,
132 max_mutation_operation_json_bytes: MAX_MUTATION_OPERATION_JSON_BYTES,
133 max_mutation_local_row_json_bytes: MAX_MUTATION_LOCAL_ROW_JSON_BYTES,
134 max_mutation_batch_json_bytes: MAX_MUTATION_BATCH_JSON_BYTES,
135 max_outbox_operations_json_bytes: MAX_OUTBOX_OPERATIONS_JSON_BYTES,
136 max_blob_payload_bytes: MAX_BLOB_PAYLOAD_BYTES,
137 max_crdt_request_json_bytes: MAX_CRDT_REQUEST_JSON_BYTES,
138 max_crdt_update_base64_bytes: MAX_CRDT_UPDATE_BASE64_BYTES,
139 max_crdt_state_base64_bytes: MAX_CRDT_STATE_BASE64_BYTES,
140 max_crdt_state_vector_base64_bytes: MAX_CRDT_STATE_VECTOR_BASE64_BYTES,
141 max_crdt_text_bytes: MAX_CRDT_TEXT_BYTES,
142 max_native_diagnostic_event_payload_json_bytes:
143 MAX_NATIVE_DIAGNOSTIC_EVENT_PAYLOAD_JSON_BYTES,
144 max_snapshot_chunk_compressed_bytes: MAX_SNAPSHOT_CHUNK_COMPRESSED_BYTES,
145 max_snapshot_chunk_decompressed_bytes: MAX_SNAPSHOT_CHUNK_DECOMPRESSED_BYTES,
146 max_snapshot_artifact_compressed_bytes: MAX_SNAPSHOT_ARTIFACT_COMPRESSED_BYTES,
147 max_snapshot_artifact_decompressed_bytes: MAX_SNAPSHOT_ARTIFACT_DECOMPRESSED_BYTES,
148 max_realtime_sync_pack_bytes: MAX_REALTIME_SYNC_PACK_BYTES,
149 max_websocket_text_frame_bytes: MAX_WEBSOCKET_TEXT_FRAME_BYTES,
150 }
151}
152
153pub fn validate_unresolved_outbox_capacity(unresolved_count: usize) -> Result<()> {
154 if unresolved_count >= DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS {
155 return Err(SyncularError::limit_exceeded(
156 "maxUnresolvedOutboxCommits",
157 unresolved_count,
158 DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS,
159 "unresolved outbox queue is full",
160 ));
161 }
162 Ok(())
163}