import Foundation // ───────────────────────────────────────────────────────────── // Load Balancer for Cross-Device Communication // ───────────────────────────────────────────────────────────── /// Load balancing strategies public enum LoadBalancingStrategy: Sendable { case roundRobin case leastLoaded case random case geographic } /// Load balancer public final class LoadBalancer: @unchecked Sendable { private var nodes: [DeviceNode] = [] private var currentIndex: Int = 0 private let strategy: LoadBalancingStrategy private let lock = NSLock() public init(strategy: LoadBalancingStrategy = .roundRobin) { self.strategy = strategy } /// Add a node public func addNode(_ node: DeviceNode) { lock.lock() defer { lock.unlock() } nodes.append(node) } /// Remove a node public func removeNode(id: String) { lock.lock() defer { lock.unlock() } nodes.removeAll { $0.id == id } } /// Get next node based on strategy public func getNextNode() -> DeviceNode? { lock.lock() defer { lock.unlock() } let healthyNodes = nodes.filter { $0.status == .healthy } guard !healthyNodes.isEmpty else { return nil } switch strategy { case .roundRobin: let node = healthyNodes[currentIndex % healthyNodes.count] currentIndex += 1 return node case .leastLoaded: return healthyNodes.min { $0.load < $1.load } case .random: return healthyNodes.randomElement() case .geographic: // Simplified: return node with lowest latency return healthyNodes.first } } /// Update node status public func updateNodeStatus(id: String, status: DeviceStatus, load: Double? = nil) { lock.lock() defer { lock.unlock() } if let index = nodes.firstIndex(where: { $0.id == id }) { var node = nodes[index] node.status = status if let load = load { node.load = load } nodes[index] = node } } /// Get all nodes public func getNodes() -> [DeviceNode] { lock.lock() defer { lock.unlock() } return nodes } /// Get healthy nodes count public var healthyNodesCount: Int { nodes.filter { $0.status == .healthy }.count } }