mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
91 lines
3.2 KiB
Swift
91 lines
3.2 KiB
Swift
import Foundation
|
|
import Observation
|
|
import os.log
|
|
|
|
/// Centralized manager for coordinating status checks of all remote services.
|
|
///
|
|
/// This manager prevents multiple views from independently polling the same services,
|
|
/// reducing network traffic and CPU usage. It provides a single source of truth for
|
|
/// service status updates across the application.
|
|
@MainActor
|
|
@Observable
|
|
final class RemoteServicesStatusManager {
|
|
static let shared = RemoteServicesStatusManager()
|
|
|
|
private var statusCheckTimer: Timer?
|
|
private let checkInterval: TimeInterval = RemoteAccessConstants.statusCheckInterval
|
|
private let logger = Logger(subsystem: BundleIdentifiers.loggerSubsystem, category: "RemoteServicesStatus")
|
|
|
|
// Service references
|
|
private let ngrokService = NgrokService.shared
|
|
private let tailscaleService = TailscaleService.shared
|
|
private let cloudflareService = CloudflareService.shared
|
|
|
|
// Status storage
|
|
private(set) var ngrokStatus: NgrokTunnelStatus?
|
|
private(set) var tailscaleStatus: (isInstalled: Bool, isRunning: Bool, hostname: String?)?
|
|
private(set) var cloudflareStatus: (isInstalled: Bool, isRunning: Bool, publicUrl: String?, error: String?)?
|
|
|
|
private init() {}
|
|
|
|
/// Start monitoring all remote services
|
|
func startMonitoring() {
|
|
guard statusCheckTimer == nil else { return }
|
|
|
|
logger.info("Starting remote services monitoring")
|
|
|
|
// Perform initial check
|
|
Task {
|
|
await checkAllServices()
|
|
}
|
|
|
|
// Set up periodic checks
|
|
statusCheckTimer = Timer.scheduledTimer(withTimeInterval: checkInterval, repeats: true) { [weak self] _ in
|
|
Task { @MainActor [weak self] in
|
|
await self?.checkAllServices()
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Stop monitoring remote services
|
|
func stopMonitoring() {
|
|
logger.info("Stopping remote services monitoring")
|
|
statusCheckTimer?.invalidate()
|
|
statusCheckTimer = nil
|
|
}
|
|
|
|
/// Check all services and update their status
|
|
private func checkAllServices() async {
|
|
logger.debug("Checking all remote services status")
|
|
|
|
// Check services in parallel
|
|
async let ngrokCheck = ngrokService.getStatus()
|
|
async let tailscaleCheck = checkTailscaleStatus()
|
|
async let cloudflareCheck: Void = cloudflareService.checkCloudflaredStatus()
|
|
|
|
// Update status
|
|
ngrokStatus = await ngrokCheck
|
|
tailscaleStatus = await tailscaleCheck
|
|
|
|
// Wait for cloudflare check to complete
|
|
await cloudflareCheck
|
|
|
|
// Get cloudflare status
|
|
cloudflareStatus = (
|
|
isInstalled: cloudflareService.isInstalled,
|
|
isRunning: cloudflareService.isRunning,
|
|
publicUrl: cloudflareService.publicUrl,
|
|
error: cloudflareService.statusError
|
|
)
|
|
}
|
|
|
|
/// Check Tailscale status
|
|
private func checkTailscaleStatus() async -> (isInstalled: Bool, isRunning: Bool, hostname: String?) {
|
|
await tailscaleService.checkTailscaleStatus()
|
|
return (
|
|
isInstalled: tailscaleService.isInstalled,
|
|
isRunning: tailscaleService.isRunning,
|
|
hostname: tailscaleService.tailscaleHostname
|
|
)
|
|
}
|
|
}
|