Files
markbaseengine/Sources/MarkBaseServer/LoadBalancer.swift
T
MarkBase Admin 8a66b9086a
CI / build (push) Waiting to run
CI / unit-tests (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
v2: Initial clean branch with unit tests + CI/CD pipeline
- Started from ac75faa (initial E4B-MarkBase integration)
- Kept Sources/ (all engine code) + Package.swift + .gitignore
- Removed all ad-hoc tests, documentation, scripts, Python files
- Added Tests/00_Unit/ (MathTest, TokenizerTest, SamplerTest)
- Added .gitea/workflows/ci.yaml (build + unit tests + lint)
- Added Scripts/check_resources.sh (memory-aware test runner)
- Added Tests/Manifest.json (resource requirements for all tests)
- Focus: 4-bit quantized models only
2026-07-05 13:29:25 +08:00

93 lines
2.7 KiB
Swift

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
}
}