use serde::Serialize;
use crate::error::{Result, SyncularError};
use crate::store::{
BLOB_UPLOAD_STALE_TIMEOUT_MS, MAX_BLOB_UPLOAD_RETRIES, MAX_SYNC_RETRIES,
SQLITE_BUSY_TIMEOUT_MS, SYNC_SENDING_TIMEOUT_MS,
};
pub const DEFAULT_WORKER_COMMAND_QUEUE_CAPACITY: usize = 1024;
pub const DEFAULT_WORKER_EVENT_QUEUE_CAPACITY: usize = 1024;
pub const DEFAULT_NATIVE_EVENT_STREAM_CAPACITY: usize = 256;
pub const DEFAULT_NATIVE_RECENT_EVENT_LIMIT: usize = 100;
pub const DEFAULT_READONLY_QUERY_STATEMENT_CACHE_CAPACITY: usize = 64;
pub const DEFAULT_PULL_LIMIT_COMMITS: i64 = 1000;
pub const DEFAULT_PULL_LIMIT_SNAPSHOT_ROWS: i64 = 50_000;
pub const DEFAULT_PULL_MAX_SNAPSHOT_PAGES: i64 = 10;
pub const DEFAULT_OUTBOX_PUSH_BATCH_LIMIT: i64 = 20;
pub const DEFAULT_ADAPTIVE_OUTBOX_PUSH_BATCH_LIMIT: i64 = MAX_OUTBOX_PUSH_BATCH_LIMIT;
pub const DEFAULT_ADAPTIVE_OUTBOX_PUSH_THRESHOLD: i64 = 100;
pub const MAX_OUTBOX_PUSH_BATCH_LIMIT: i64 = 1000;
pub const DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS: usize = 10_000;
pub const DEFAULT_BLOB_UPLOAD_BATCH_LIMIT: i64 = 10;
pub const DEFAULT_CRDT_STATE_VECTOR_HINT_LIMIT: i64 = 256;
pub const DEFAULT_CRDT_UPDATE_QUEUE_CAPACITY: i64 = 1024;
pub const DEFAULT_CRDT_UPDATE_LOG_LIMIT: i64 = 100;
pub const DEFAULT_YJS_FLUSH_WINDOW_MS: u64 = 12;
pub const MAX_SUBSCRIPTIONS_PER_CLIENT: usize = 256;
pub const MAX_SCOPE_KEYS_PER_SUBSCRIPTION: usize = 16;
pub const MAX_SCOPE_VALUES_PER_SUBSCRIPTION: usize = 4096;
pub const MAX_SCOPE_VALUES_PER_CLIENT: usize = 16_384;
pub const MAX_SUBSCRIPTION_PARAMS_PER_SUBSCRIPTION: usize = 32;
pub const MAX_MUTATION_OPERATION_JSON_BYTES: usize = 1024 * 1024;
pub const MAX_MUTATION_LOCAL_ROW_JSON_BYTES: usize = 1024 * 1024;
pub const MAX_MUTATION_BATCH_JSON_BYTES: usize = 4 * 1024 * 1024;
pub const MAX_OUTBOX_OPERATIONS_JSON_BYTES: usize = 4 * 1024 * 1024;
pub const MAX_BLOB_PAYLOAD_BYTES: i64 = 64 * 1024 * 1024;
pub const MAX_CRDT_REQUEST_JSON_BYTES: usize = 4 * 1024 * 1024;
pub const MAX_CRDT_UPDATE_BASE64_BYTES: usize = 1024 * 1024;
pub const MAX_CRDT_STATE_BASE64_BYTES: usize = 4 * 1024 * 1024;
pub const MAX_CRDT_STATE_VECTOR_BASE64_BYTES: usize = 64 * 1024;
pub const MAX_CRDT_TEXT_BYTES: usize = 1024 * 1024;
pub const MAX_NATIVE_DIAGNOSTIC_EVENT_PAYLOAD_JSON_BYTES: usize = 16 * 1024;
pub const MAX_SNAPSHOT_CHUNK_COMPRESSED_BYTES: i64 = 64 * 1024 * 1024;
pub const MAX_SNAPSHOT_CHUNK_DECOMPRESSED_BYTES: usize = 256 * 1024 * 1024;
pub const MAX_SNAPSHOT_ARTIFACT_COMPRESSED_BYTES: i64 = 256 * 1024 * 1024;
pub const MAX_SNAPSHOT_ARTIFACT_DECOMPRESSED_BYTES: usize = 512 * 1024 * 1024;
pub const MAX_REALTIME_SYNC_PACK_BYTES: usize = 16 * 1024 * 1024;
pub const MAX_WEBSOCKET_TEXT_FRAME_BYTES: usize = 8 * 1024 * 1024;
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RuntimeLimits {
pub worker_command_queue_capacity: usize,
pub worker_event_queue_capacity: usize,
pub native_default_event_stream_capacity: usize,
pub native_recent_event_limit: usize,
pub readonly_query_statement_cache_capacity: usize,
pub pull_limit_commits: i64,
pub pull_limit_snapshot_rows: i64,
pub pull_max_snapshot_pages: i64,
pub outbox_push_batch_limit: i64,
pub adaptive_outbox_push_batch_limit: i64,
pub adaptive_outbox_push_threshold: i64,
pub max_unresolved_outbox_commits: usize,
pub max_sync_retries: i32,
pub sync_sending_timeout_ms: i64,
pub max_blob_upload_retries: i32,
pub blob_upload_stale_timeout_ms: i64,
pub blob_upload_batch_limit: i64,
pub sqlite_busy_timeout_ms: i32,
pub crdt_state_vector_hint_limit: i64,
pub crdt_update_queue_capacity: i64,
pub crdt_update_log_default_limit: i64,
pub yjs_flush_window_ms: u64,
pub max_subscriptions_per_client: usize,
pub max_scope_keys_per_subscription: usize,
pub max_scope_values_per_subscription: usize,
pub max_scope_values_per_client: usize,
pub max_subscription_params_per_subscription: usize,
pub max_mutation_operation_json_bytes: usize,
pub max_mutation_local_row_json_bytes: usize,
pub max_mutation_batch_json_bytes: usize,
pub max_outbox_operations_json_bytes: usize,
pub max_blob_payload_bytes: i64,
pub max_crdt_request_json_bytes: usize,
pub max_crdt_update_base64_bytes: usize,
pub max_crdt_state_base64_bytes: usize,
pub max_crdt_state_vector_base64_bytes: usize,
pub max_crdt_text_bytes: usize,
pub max_native_diagnostic_event_payload_json_bytes: usize,
pub max_snapshot_chunk_compressed_bytes: i64,
pub max_snapshot_chunk_decompressed_bytes: usize,
pub max_snapshot_artifact_compressed_bytes: i64,
pub max_snapshot_artifact_decompressed_bytes: usize,
pub max_realtime_sync_pack_bytes: usize,
pub max_websocket_text_frame_bytes: usize,
}
pub fn runtime_default_limits() -> RuntimeLimits {
RuntimeLimits {
worker_command_queue_capacity: DEFAULT_WORKER_COMMAND_QUEUE_CAPACITY,
worker_event_queue_capacity: DEFAULT_WORKER_EVENT_QUEUE_CAPACITY,
native_default_event_stream_capacity: DEFAULT_NATIVE_EVENT_STREAM_CAPACITY,
native_recent_event_limit: DEFAULT_NATIVE_RECENT_EVENT_LIMIT,
readonly_query_statement_cache_capacity: DEFAULT_READONLY_QUERY_STATEMENT_CACHE_CAPACITY,
pull_limit_commits: DEFAULT_PULL_LIMIT_COMMITS,
pull_limit_snapshot_rows: DEFAULT_PULL_LIMIT_SNAPSHOT_ROWS,
pull_max_snapshot_pages: DEFAULT_PULL_MAX_SNAPSHOT_PAGES,
outbox_push_batch_limit: DEFAULT_OUTBOX_PUSH_BATCH_LIMIT,
adaptive_outbox_push_batch_limit: DEFAULT_ADAPTIVE_OUTBOX_PUSH_BATCH_LIMIT,
adaptive_outbox_push_threshold: DEFAULT_ADAPTIVE_OUTBOX_PUSH_THRESHOLD,
max_unresolved_outbox_commits: DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS,
max_sync_retries: MAX_SYNC_RETRIES,
sync_sending_timeout_ms: SYNC_SENDING_TIMEOUT_MS,
max_blob_upload_retries: MAX_BLOB_UPLOAD_RETRIES,
blob_upload_stale_timeout_ms: BLOB_UPLOAD_STALE_TIMEOUT_MS,
blob_upload_batch_limit: DEFAULT_BLOB_UPLOAD_BATCH_LIMIT,
sqlite_busy_timeout_ms: SQLITE_BUSY_TIMEOUT_MS,
crdt_state_vector_hint_limit: DEFAULT_CRDT_STATE_VECTOR_HINT_LIMIT,
crdt_update_queue_capacity: DEFAULT_CRDT_UPDATE_QUEUE_CAPACITY,
crdt_update_log_default_limit: DEFAULT_CRDT_UPDATE_LOG_LIMIT,
yjs_flush_window_ms: DEFAULT_YJS_FLUSH_WINDOW_MS,
max_subscriptions_per_client: MAX_SUBSCRIPTIONS_PER_CLIENT,
max_scope_keys_per_subscription: MAX_SCOPE_KEYS_PER_SUBSCRIPTION,
max_scope_values_per_subscription: MAX_SCOPE_VALUES_PER_SUBSCRIPTION,
max_scope_values_per_client: MAX_SCOPE_VALUES_PER_CLIENT,
max_subscription_params_per_subscription: MAX_SUBSCRIPTION_PARAMS_PER_SUBSCRIPTION,
max_mutation_operation_json_bytes: MAX_MUTATION_OPERATION_JSON_BYTES,
max_mutation_local_row_json_bytes: MAX_MUTATION_LOCAL_ROW_JSON_BYTES,
max_mutation_batch_json_bytes: MAX_MUTATION_BATCH_JSON_BYTES,
max_outbox_operations_json_bytes: MAX_OUTBOX_OPERATIONS_JSON_BYTES,
max_blob_payload_bytes: MAX_BLOB_PAYLOAD_BYTES,
max_crdt_request_json_bytes: MAX_CRDT_REQUEST_JSON_BYTES,
max_crdt_update_base64_bytes: MAX_CRDT_UPDATE_BASE64_BYTES,
max_crdt_state_base64_bytes: MAX_CRDT_STATE_BASE64_BYTES,
max_crdt_state_vector_base64_bytes: MAX_CRDT_STATE_VECTOR_BASE64_BYTES,
max_crdt_text_bytes: MAX_CRDT_TEXT_BYTES,
max_native_diagnostic_event_payload_json_bytes:
MAX_NATIVE_DIAGNOSTIC_EVENT_PAYLOAD_JSON_BYTES,
max_snapshot_chunk_compressed_bytes: MAX_SNAPSHOT_CHUNK_COMPRESSED_BYTES,
max_snapshot_chunk_decompressed_bytes: MAX_SNAPSHOT_CHUNK_DECOMPRESSED_BYTES,
max_snapshot_artifact_compressed_bytes: MAX_SNAPSHOT_ARTIFACT_COMPRESSED_BYTES,
max_snapshot_artifact_decompressed_bytes: MAX_SNAPSHOT_ARTIFACT_DECOMPRESSED_BYTES,
max_realtime_sync_pack_bytes: MAX_REALTIME_SYNC_PACK_BYTES,
max_websocket_text_frame_bytes: MAX_WEBSOCKET_TEXT_FRAME_BYTES,
}
}
pub fn validate_unresolved_outbox_capacity(unresolved_count: usize) -> Result<()> {
if unresolved_count >= DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS {
return Err(SyncularError::limit_exceeded(
"maxUnresolvedOutboxCommits",
unresolved_count,
DEFAULT_MAX_UNRESOLVED_OUTBOX_COMMITS,
"unresolved outbox queue is full",
));
}
Ok(())
}