Skip to main content

mj_controller/
server_runtime.rs

1//! The phone-oriented remote-control server: its HTTP surface, the controller
2//! actions phones request, and the concurrency limits that keep them safe.
3
4use std::net::{Ipv4Addr, SocketAddr};
5use std::path::PathBuf;
6use std::sync::Arc;
7use std::sync::atomic::{AtomicBool, Ordering};
8use std::time::{Duration, Instant};
9
10use anyhow::{Context, Result, bail};
11mod api;
12mod api_activity;
13mod profile_catalog;
14
15use mj_core::config::{Config, HarnessProfile, PhoneConfig, is_bare_project_target};
16use mj_core::refusal::Refusal;
17use mj_core::remote_git::{default_branch, display_url, resolve_repository};
18use mj_core::state::{MaterializedSession, ProjectSourceIdentity, SessionRecord, State};
19
20use crate::controller::Controller;
21use crate::quota::ProfileQuota;
22use crate::server::{
23    ActionOutcome, BackgroundTaskStopFailure, BackgroundTaskStopRequest, BrowserTranscript,
24    ControllerAction, ControllerRequest, MovePreparationRequest, PreflightFailure,
25    ReadReceiptRequest, ResumeQueueDisposition, ServerOptions, ViewerActivityDetails,
26    ViewerActivityKind, ViewerBackgroundTask, ViewerMoveRecovery, ViewerQueuedPrompt, ViewerQuota,
27    ViewerSnapshot, ViewerUserShell,
28};
29use crate::session_manager::{SessionManagerChannels, SessionManagerControl, new_command_id};
30use crate::tailscale::TailscaleTls;
31#[cfg(test)]
32use crate::targets::ProcessExecutor;
33use crate::targets::{CancellableProcessExecutor, CommandExecutor};
34use crate::worker_client::CredentialSyncCoordinator;
35use mj_core::relay::RelayCommand;
36use mj_core::workspace::WorkspaceRecord;
37
38use crate::controller::config_only_controller;
39use crate::daemon::{
40    CreateSessionControl, CreateSessionRequest, ResumeSessionRequest, RuntimeState,
41};
42use crate::pollers::{
43    CredentialSyncNotices, CredentialSyncSignalTracker, QUOTA_STALE_AFTER, QuotaRefreshBatch,
44    QuotaUpdate, apply_worker_record_update, credential_sync_targets, dashboard_worker_targets,
45    projected_queued_prompts, queued_prompt_projection, quota_refresh_profiles,
46    schedule_due_credential_syncs, spawn_quota_refresher,
47};
48
49#[derive(Debug, Clone)]
50pub struct ServerArgs {
51    bind: String,
52    tailscale_detect: bool,
53    tls_cert: Option<PathBuf>,
54    tls_key: Option<PathBuf>,
55}
56
57impl From<&PhoneConfig> for ServerArgs {
58    fn from(config: &PhoneConfig) -> Self {
59        Self {
60            bind: config.bind.clone(),
61            tailscale_detect: config.tailscale_detect,
62            tls_cert: config.tls_cert.clone(),
63            tls_key: config.tls_key.clone(),
64        }
65    }
66}
67
68const TAILSCALE_COMMAND_TIMEOUT: Duration = Duration::from_secs(120);
69const TAILSCALE_RENEW_INTERVAL: Duration = Duration::from_secs(24 * 60 * 60);
70
71mod projection;
72use projection::*;
73mod args;
74use args::*;
75mod phone_actions;
76use phone_actions::*;
77mod run;
78pub use run::*;
79mod support;
80use support::*;
81mod preflight;
82use preflight::*;
83mod actions;
84use actions::*;
85mod project_sources;
86use project_sources::*;
87mod snapshot;
88use snapshot::*;
89
90#[cfg(test)]
91mod tests;