2181 lines · 80.9 KB · Rust
RawDownload
#![forbid(unsafe_code)] //! Process-owned trusted runtime services.//!//! Production sidecars construct exactly one [`SidecarRuntime`] at their//! process entrypoint. Subsystems receive a clone of [`RuntimeContext`]; they//! never construct Tokio runtimes of their own. use std::cell::Cell;use std::fmt;use std::future::Future;use std::pin::Pin;use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};use std::sync::{mpsc, Arc, Mutex, OnceLock};use std::task::{Context, Poll};use std::thread;use std::time::{Duration, Instant}; use accounting::{LimitError, Reservation, ResourceClass, ResourceLedger, ResourceLimit};use fairness::{FairBudget, FairWorkBroker, FairnessConfig};use metrics::{    ExecutorMetricClass, RuntimeMetrics, TelemetryFallback, TelemetryFallbackCode,    TelemetrySeverity, TelemetrySubsystem, WatchdogMetric,}; pub mod accounting;pub mod capability;pub mod fairness;pub mod metrics;pub mod readiness;pub mod supervision; pub use supervision::{    TaskClass, TaskClassSnapshot, TaskOwner, TaskSpawnError, TaskSupervisor, TaskTerminalReason,    TaskTerminalReport,}; const DEFAULT_MAX_BLOCKING_JOB_BYTES: usize = 64 * 1024 * 1024;const DEFAULT_BLOCKING_JOB_TIMEOUT_MS: u64 = 30_000;const DEFAULT_MAX_BLOCKING_JOBS: usize = 1_028;const DEFAULT_MAX_QUEUED_BLOCKING_JOBS: usize = 1024;const DEFAULT_MAX_PROCESS_CAPABILITIES: usize = 16_384;const DEFAULT_MAX_PROCESS_SOCKETS: usize = 8_192;const DEFAULT_MAX_PROCESS_CONNECTIONS: usize = 8_192;const DEFAULT_MAX_PROCESS_SOCKET_BUFFERED_BYTES: usize = 1024 * 1024 * 1024;const DEFAULT_MAX_PROCESS_DATAGRAMS: usize = 65_536;const DEFAULT_MAX_PROCESS_TIMERS: usize = 65_536;const DEFAULT_MAX_PROCESS_TASKS: usize = 65_536;const DEFAULT_MAX_PROCESS_READY_HANDLES: usize = 16_384;const DEFAULT_MAX_PROCESS_HANDLE_COMMANDS: usize = 65_536;const DEFAULT_MAX_PROCESS_HANDLE_COMMAND_BYTES: usize = 256 * 1024 * 1024;const DEFAULT_MAX_PROCESS_BRIDGE_CALLS: usize = 65_536;const DEFAULT_MAX_PROCESS_BRIDGE_REQUEST_BYTES: usize = 256 * 1024 * 1024;const DEFAULT_MAX_PROCESS_BRIDGE_RESPONSE_BYTES: usize = 256 * 1024 * 1024;const DEFAULT_MAX_PROCESS_ASYNC_COMPLETIONS: usize = 65_536;const DEFAULT_MAX_PROCESS_ASYNC_COMPLETION_BYTES: usize = 256 * 1024 * 1024;const DEFAULT_MAX_PROCESS_UDP_DATAGRAMS: usize = 65_536;const DEFAULT_MAX_PROCESS_UDP_BYTES: usize = 256 * 1024 * 1024;const DEFAULT_MAX_PROCESS_TLS_BYTES: usize = 256 * 1024 * 1024;const DEFAULT_MAX_PROCESS_HTTP2_CONNECTIONS: usize = 4_096;const DEFAULT_MAX_PROCESS_HTTP2_STREAMS: usize = 65_536;const DEFAULT_MAX_PROCESS_HTTP2_BYTES: usize = 512 * 1024 * 1024;const DEFAULT_MAX_PROCESS_HTTP2_HEADER_BYTES: usize = 128 * 1024 * 1024;const DEFAULT_MAX_PROCESS_HTTP2_DATA_BYTES: usize = 512 * 1024 * 1024;const DEFAULT_MAX_PROCESS_HTTP2_COMMANDS: usize = 65_536;const DEFAULT_MAX_PROCESS_HTTP2_COMMAND_BYTES: usize = 256 * 1024 * 1024;const DEFAULT_MAX_PROCESS_HTTP2_EVENTS: usize = 65_536;const DEFAULT_MAX_PROCESS_HTTP2_EVENT_BYTES: usize = 512 * 1024 * 1024;const DEFAULT_TASK_POLL_WATCHDOG_MS: u64 = 100;const DEFAULT_MAX_TERMINAL_TASK_REPORTS: usize = 4_096;const DEFAULT_VM_EXECUTOR_TEARDOWN_TIMEOUT_MS: u64 = 5_000;pub const DEFAULT_PROTOCOL_MAX_INGRESS_FRAMES: usize = 128;pub const DEFAULT_PROTOCOL_MAX_INGRESS_BYTES: usize = 64 * 1024 * 1024;pub const DEFAULT_PROTOCOL_MAX_CONTROL_FRAMES: usize = 1_024;pub const DEFAULT_PROTOCOL_MAX_CONTROL_BYTES: usize = 64 * 1024 * 1024;pub const DEFAULT_PROTOCOL_MAX_EGRESS_FRAMES: usize = 4_096;pub const DEFAULT_PROTOCOL_MAX_EGRESS_BYTES: usize = 256 * 1024 * 1024;pub const DEFAULT_PROTOCOL_MAX_PENDING_RESPONSES: usize = 10_000;pub const DEFAULT_PROTOCOL_MAX_PENDING_RESPONSE_BYTES: usize = 256 * 1024 * 1024;pub const DEFAULT_PROTOCOL_MAX_PROCESS_EVENTS: usize = 10_000;pub const DEFAULT_PROTOCOL_MAX_OUTBOUND_REQUESTS: usize = 10_000;pub const DEFAULT_PROTOCOL_MAX_COMPLETED_RESPONSES: usize = 10_000;const DEFAULT_FAIRNESS_VM_OPERATIONS: usize = 64;const DEFAULT_FAIRNESS_VM_BYTES: usize = 1024 * 1024;const DEFAULT_FAIRNESS_CAPABILITY_OPERATIONS: usize = 16;const DEFAULT_FAIRNESS_CAPABILITY_BYTES: usize = 256 * 1024;const DEFAULT_FAIRNESS_MAX_VMS: usize = 4_096;const DEFAULT_FAIRNESS_MAX_CAPABILITIES_PER_VM: usize = 16_384; thread_local! {    static IS_AGENTOS_RUNTIME_WORKER: Cell<bool> = const { Cell::new(false) };} /// Whether the current OS thread is one of the process runtime's fixed workers.////// Synchronous compatibility adapters use this to reject waits that would/// consume a trusted runtime worker and could deadlock the work they submitted.pub fn is_runtime_worker_thread() -> bool {    IS_AGENTOS_RUNTIME_WORKER.with(Cell::get)} /// Process-owned bounds for the multiplexed sidecar transport.////// Ordinary frames and response/control frames have independent admission so/// an event or request backlog cannot consume the capacity needed to settle an/// already-registered bridge call. Byte ceilings cover retained decoded or/// encoded frames; the one active decoder is separately bounded by the wire/// codec's `max_frame_bytes` setting.#[derive(Clone, Debug, PartialEq, Eq)]pub struct RuntimeProtocolConfig {    pub max_ingress_frames: usize,    pub max_ingress_bytes: usize,    pub max_control_frames: usize,    pub max_control_bytes: usize,    pub max_egress_frames: usize,    pub max_egress_bytes: usize,    pub max_pending_responses: usize,    pub max_pending_response_bytes: usize,    pub max_process_events: usize,    pub max_outbound_requests: usize,    pub max_completed_responses: usize,} impl Default for RuntimeProtocolConfig {    fn default() -> Self {        Self {            max_ingress_frames: DEFAULT_PROTOCOL_MAX_INGRESS_FRAMES,            max_ingress_bytes: DEFAULT_PROTOCOL_MAX_INGRESS_BYTES,            max_control_frames: DEFAULT_PROTOCOL_MAX_CONTROL_FRAMES,            max_control_bytes: DEFAULT_PROTOCOL_MAX_CONTROL_BYTES,            max_egress_frames: DEFAULT_PROTOCOL_MAX_EGRESS_FRAMES,            max_egress_bytes: DEFAULT_PROTOCOL_MAX_EGRESS_BYTES,            max_pending_responses: DEFAULT_PROTOCOL_MAX_PENDING_RESPONSES,            max_pending_response_bytes: DEFAULT_PROTOCOL_MAX_PENDING_RESPONSE_BYTES,            max_process_events: DEFAULT_PROTOCOL_MAX_PROCESS_EVENTS,            max_outbound_requests: DEFAULT_PROTOCOL_MAX_OUTBOUND_REQUESTS,            max_completed_responses: DEFAULT_PROTOCOL_MAX_COMPLETED_RESPONSES,        }    }} #[derive(Clone, Debug, PartialEq, Eq)]pub struct RuntimeFairnessConfig {    pub vm_quantum_operations: usize,    pub vm_quantum_bytes: usize,    pub capability_quantum_operations: usize,    pub capability_quantum_bytes: usize,    pub max_vm_deficit_operations: usize,    pub max_vm_deficit_bytes: usize,    pub max_capability_deficit_operations: usize,    pub max_capability_deficit_bytes: usize,    pub max_vms: usize,    pub max_capabilities_per_vm: usize,} impl Default for RuntimeFairnessConfig {    fn default() -> Self {        Self {            vm_quantum_operations: DEFAULT_FAIRNESS_VM_OPERATIONS,            vm_quantum_bytes: DEFAULT_FAIRNESS_VM_BYTES,            capability_quantum_operations: DEFAULT_FAIRNESS_CAPABILITY_OPERATIONS,            capability_quantum_bytes: DEFAULT_FAIRNESS_CAPABILITY_BYTES,            max_vm_deficit_operations: DEFAULT_FAIRNESS_VM_OPERATIONS * 4,            max_vm_deficit_bytes: DEFAULT_FAIRNESS_VM_BYTES * 4,            max_capability_deficit_operations: DEFAULT_FAIRNESS_CAPABILITY_OPERATIONS * 4,            max_capability_deficit_bytes: DEFAULT_FAIRNESS_CAPABILITY_BYTES * 4,            max_vms: DEFAULT_FAIRNESS_MAX_VMS,            max_capabilities_per_vm: DEFAULT_FAIRNESS_MAX_CAPABILITIES_PER_VM,        }    }} impl RuntimeFairnessConfig {    fn scheduler_config(&self) -> FairnessConfig {        FairnessConfig {            vm_quantum: FairBudget::new(self.vm_quantum_operations, self.vm_quantum_bytes),            capability_quantum: FairBudget::new(                self.capability_quantum_operations,                self.capability_quantum_bytes,            ),            max_vm_deficit: FairBudget::new(                self.max_vm_deficit_operations,                self.max_vm_deficit_bytes,            ),            max_capability_deficit: FairBudget::new(                self.max_capability_deficit_operations,                self.max_capability_deficit_bytes,            ),            max_vms: self.max_vms,            max_capabilities_per_vm: self.max_capabilities_per_vm,        }    }} #[derive(Clone, Debug, PartialEq, Eq)]pub struct RuntimeResourceConfig {    pub max_capabilities: usize,    pub max_ready_handles: usize,    pub max_sockets: usize,    pub max_connections: usize,    pub max_socket_buffered_bytes: usize,    pub max_datagrams: usize,    pub max_timers: usize,    pub max_tasks: usize,    pub max_handle_commands: usize,    pub max_handle_command_bytes: usize,    pub max_bridge_calls: usize,    pub max_bridge_request_bytes: usize,    pub max_bridge_response_bytes: usize,    pub max_async_completions: usize,    pub max_async_completion_bytes: usize,    pub max_udp_datagrams: usize,    pub max_udp_bytes: usize,    pub max_tls_bytes: usize,    pub max_http2_connections: usize,    pub max_http2_streams: usize,    pub max_http2_buffered_bytes: usize,    pub max_http2_header_bytes: usize,    pub max_http2_data_bytes: usize,    pub max_http2_commands: usize,    pub max_http2_command_bytes: usize,    pub max_http2_events: usize,    pub max_http2_event_bytes: usize,} impl Default for RuntimeResourceConfig {    fn default() -> Self {        Self {            max_capabilities: DEFAULT_MAX_PROCESS_CAPABILITIES,            max_ready_handles: DEFAULT_MAX_PROCESS_READY_HANDLES,            max_sockets: DEFAULT_MAX_PROCESS_SOCKETS,            max_connections: DEFAULT_MAX_PROCESS_CONNECTIONS,            max_socket_buffered_bytes: DEFAULT_MAX_PROCESS_SOCKET_BUFFERED_BYTES,            max_datagrams: DEFAULT_MAX_PROCESS_DATAGRAMS,            max_timers: DEFAULT_MAX_PROCESS_TIMERS,            max_tasks: DEFAULT_MAX_PROCESS_TASKS,            max_handle_commands: DEFAULT_MAX_PROCESS_HANDLE_COMMANDS,            max_handle_command_bytes: DEFAULT_MAX_PROCESS_HANDLE_COMMAND_BYTES,            max_bridge_calls: DEFAULT_MAX_PROCESS_BRIDGE_CALLS,            max_bridge_request_bytes: DEFAULT_MAX_PROCESS_BRIDGE_REQUEST_BYTES,            max_bridge_response_bytes: DEFAULT_MAX_PROCESS_BRIDGE_RESPONSE_BYTES,            max_async_completions: DEFAULT_MAX_PROCESS_ASYNC_COMPLETIONS,            max_async_completion_bytes: DEFAULT_MAX_PROCESS_ASYNC_COMPLETION_BYTES,            max_udp_datagrams: DEFAULT_MAX_PROCESS_UDP_DATAGRAMS,            max_udp_bytes: DEFAULT_MAX_PROCESS_UDP_BYTES,            max_tls_bytes: DEFAULT_MAX_PROCESS_TLS_BYTES,            max_http2_connections: DEFAULT_MAX_PROCESS_HTTP2_CONNECTIONS,            max_http2_streams: DEFAULT_MAX_PROCESS_HTTP2_STREAMS,            max_http2_buffered_bytes: DEFAULT_MAX_PROCESS_HTTP2_BYTES,            max_http2_header_bytes: DEFAULT_MAX_PROCESS_HTTP2_HEADER_BYTES,            max_http2_data_bytes: DEFAULT_MAX_PROCESS_HTTP2_DATA_BYTES,            max_http2_commands: DEFAULT_MAX_PROCESS_HTTP2_COMMANDS,            max_http2_command_bytes: DEFAULT_MAX_PROCESS_HTTP2_COMMAND_BYTES,            max_http2_events: DEFAULT_MAX_PROCESS_HTTP2_EVENTS,            max_http2_event_bytes: DEFAULT_MAX_PROCESS_HTTP2_EVENT_BYTES,        }    }} impl RuntimeResourceConfig {    fn limits(&self) -> Vec<(ResourceClass, ResourceLimit)> {        vec![            (                ResourceClass::Capabilities,                ResourceLimit::new(self.max_capabilities, "runtime.resources.maxCapabilities"),            ),            (                ResourceClass::ReadyHandles,                ResourceLimit::new(self.max_ready_handles, "runtime.resources.maxReadyHandles"),            ),            (                ResourceClass::Sockets,                ResourceLimit::new(self.max_sockets, "runtime.resources.maxSockets"),            ),            (                ResourceClass::Connections,                ResourceLimit::new(self.max_connections, "runtime.resources.maxConnections"),            ),            (                ResourceClass::BufferedBytes,                ResourceLimit::new(                    self.max_socket_buffered_bytes,                    "runtime.resources.maxSocketBufferedBytes",                ),            ),            (                ResourceClass::Datagrams,                ResourceLimit::new(self.max_datagrams, "runtime.resources.maxDatagrams"),            ),            (                ResourceClass::Timers,                ResourceLimit::new(self.max_timers, "runtime.resources.maxTimers"),            ),            (                ResourceClass::Tasks,                ResourceLimit::new(self.max_tasks, "runtime.resources.maxTasks"),            ),            (                ResourceClass::HandleCommands,                ResourceLimit::new(                    self.max_handle_commands,                    "runtime.resources.maxHandleCommands",                ),            ),            (                ResourceClass::HandleCommandBytes,                ResourceLimit::new(                    self.max_handle_command_bytes,                    "runtime.resources.maxHandleCommandBytes",                ),            ),            (                ResourceClass::BridgeCalls,                ResourceLimit::new(self.max_bridge_calls, "runtime.resources.maxBridgeCalls"),            ),            (                ResourceClass::BridgeRequestBytes,                ResourceLimit::new(                    self.max_bridge_request_bytes,                    "runtime.resources.maxBridgeRequestBytes",                ),            ),            (                ResourceClass::BridgeResponseBytes,                ResourceLimit::new(                    self.max_bridge_response_bytes,                    "runtime.resources.maxBridgeResponseBytes",                ),            ),            (                ResourceClass::AsyncCompletions,                ResourceLimit::new(                    self.max_async_completions,                    "runtime.resources.maxAsyncCompletions",                ),            ),            (                ResourceClass::AsyncCompletionBytes,                ResourceLimit::new(                    self.max_async_completion_bytes,                    "runtime.resources.maxAsyncCompletionBytes",                ),            ),            (                ResourceClass::UdpDatagrams,                ResourceLimit::new(self.max_udp_datagrams, "runtime.resources.maxUdpDatagrams"),            ),            (                ResourceClass::UdpBytes,                ResourceLimit::new(self.max_udp_bytes, "runtime.resources.maxUdpBytes"),            ),            (                ResourceClass::TlsBytes,                ResourceLimit::new(self.max_tls_bytes, "runtime.resources.maxTlsBytes"),            ),            (                ResourceClass::Http2Connections,                ResourceLimit::new(                    self.max_http2_connections,                    "runtime.resources.maxHttp2Connections",                ),            ),            (                ResourceClass::Http2Streams,                ResourceLimit::new(self.max_http2_streams, "runtime.resources.maxHttp2Streams"),            ),            (                ResourceClass::Http2BufferedBytes,                ResourceLimit::new(                    self.max_http2_buffered_bytes,                    "runtime.resources.maxHttp2BufferedBytes",                ),            ),            (                ResourceClass::Http2HeaderBytes,                ResourceLimit::new(                    self.max_http2_header_bytes,                    "runtime.resources.maxHttp2HeaderBytes",                ),            ),            (                ResourceClass::Http2DataBytes,                ResourceLimit::new(                    self.max_http2_data_bytes,                    "runtime.resources.maxHttp2DataBytes",                ),            ),            (                ResourceClass::Http2Commands,                ResourceLimit::new(                    self.max_http2_commands,                    "runtime.resources.maxHttp2Commands",                ),            ),            (                ResourceClass::Http2CommandBytes,                ResourceLimit::new(                    self.max_http2_command_bytes,                    "runtime.resources.maxHttp2CommandBytes",                ),            ),            (                ResourceClass::Http2Events,                ResourceLimit::new(self.max_http2_events, "runtime.resources.maxHttp2Events"),            ),            (                ResourceClass::Http2EventBytes,                ResourceLimit::new(                    self.max_http2_event_bytes,                    "runtime.resources.maxHttp2EventBytes",                ),            ),        ]    }} #[derive(Clone, Debug, PartialEq, Eq)]pub struct RuntimeConfig {    pub worker_threads: usize,    pub max_active_vm_executors: usize,    pub vm_executor_teardown_timeout_ms: u64,    pub blocking_worker_threads: usize,    pub max_blocking_jobs: usize,    pub max_queued_blocking_jobs: usize,    pub max_blocking_job_bytes: usize,    pub blocking_job_timeout_ms: u64,    pub task_poll_watchdog_ms: u64,    pub max_terminal_task_reports: usize,    pub protocol: RuntimeProtocolConfig,    pub resources: RuntimeResourceConfig,    pub fairness: RuntimeFairnessConfig,} impl Default for RuntimeConfig {    fn default() -> Self {        let available = thread::available_parallelism()            .map(usize::from)            .unwrap_or(1);        Self {            worker_threads: available.clamp(1, 4),            max_active_vm_executors: available.max(1),            vm_executor_teardown_timeout_ms: DEFAULT_VM_EXECUTOR_TEARDOWN_TIMEOUT_MS,            blocking_worker_threads: available.clamp(1, 4),            max_blocking_jobs: DEFAULT_MAX_BLOCKING_JOBS,            max_queued_blocking_jobs: DEFAULT_MAX_QUEUED_BLOCKING_JOBS,            max_blocking_job_bytes: DEFAULT_MAX_BLOCKING_JOB_BYTES,            blocking_job_timeout_ms: DEFAULT_BLOCKING_JOB_TIMEOUT_MS,            task_poll_watchdog_ms: DEFAULT_TASK_POLL_WATCHDOG_MS,            max_terminal_task_reports: DEFAULT_MAX_TERMINAL_TASK_REPORTS,            protocol: RuntimeProtocolConfig::default(),            resources: RuntimeResourceConfig::default(),            fairness: RuntimeFairnessConfig::default(),        }    }} impl RuntimeConfig {    pub fn validate(&self) -> Result<(), RuntimeBuildError> {        for (field, value) in [            ("runtime.workerThreads", self.worker_threads),            (                "runtime.executor.maxActiveVms",                self.max_active_vm_executors,            ),            (                "runtime.blocking.workerThreads",                self.blocking_worker_threads,            ),            ("runtime.blocking.maxJobs", self.max_blocking_jobs),            (                "runtime.blocking.maxQueuedJobs",                self.max_queued_blocking_jobs,            ),            (                "runtime.blocking.maxQueuedBytes",                self.max_blocking_job_bytes,            ),            (                "runtime.tasks.maxTerminalReports",                self.max_terminal_task_reports,            ),            (                "runtime.protocol.maxIngressFrames",                self.protocol.max_ingress_frames,            ),            (                "runtime.protocol.maxIngressBytes",                self.protocol.max_ingress_bytes,            ),            (                "runtime.protocol.maxControlFrames",                self.protocol.max_control_frames,            ),            (                "runtime.protocol.maxControlBytes",                self.protocol.max_control_bytes,            ),            (                "runtime.protocol.maxEgressFrames",                self.protocol.max_egress_frames,

Lines 1–500 of 2181.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t