91 lines
2.7 KiB
Swift
91 lines
2.7 KiB
Swift
import ArgumentParser
|
|
import CliClient
|
|
import Dependencies
|
|
import Foundation
|
|
import Logging
|
|
import Models
|
|
import MQTTConnectionService
|
|
import MQTTManager
|
|
import MQTTNIO
|
|
import NIO
|
|
import PsychrometricClientLive
|
|
import SensorsService
|
|
import ServiceLifecycle
|
|
|
|
extension Application {
|
|
/// Run the controller.
|
|
///
|
|
struct Run: AsyncParsableCommand {
|
|
|
|
static let configuration = CommandConfiguration(
|
|
commandName: "run",
|
|
abstract: "Run the controller."
|
|
)
|
|
|
|
@OptionGroup
|
|
var options: SharedOptions
|
|
|
|
mutating func run() async throws {
|
|
@Dependency(\.cliClient) var cliClient
|
|
|
|
let (mqtt, logger) = try await cliClient.setupRun(options: options)
|
|
logger.info("Setting up environment...")
|
|
|
|
do {
|
|
try await withDependencies {
|
|
$0.psychrometricClient = .liveValue
|
|
$0.mqtt = .live(client: mqtt, logger: logger)
|
|
} operation: {
|
|
let mqttConnection = MQTTConnectionService(logger: logger)
|
|
let sensors = SensorsService(sensors: .live, logger: logger)
|
|
|
|
var serviceGroupConfiguration = ServiceGroupConfiguration(
|
|
services: [
|
|
mqttConnection,
|
|
sensors
|
|
],
|
|
gracefulShutdownSignals: [.sigterm, .sigint],
|
|
logger: logger
|
|
)
|
|
// These settings prevent services from running forever after we've
|
|
// received a shutdown signal. In general it should not needed unless the
|
|
// services don't shutdown their async streams properly.
|
|
serviceGroupConfiguration.maximumCancellationDuration = .seconds(5)
|
|
serviceGroupConfiguration.maximumGracefulShutdownDuration = .seconds(10)
|
|
|
|
let serviceGroup = ServiceGroup(configuration: serviceGroupConfiguration)
|
|
|
|
logger.info("Starting dewpoint-controller!")
|
|
try await serviceGroup.run()
|
|
}
|
|
|
|
// Here we've received a shutdown signal and shutdown all the
|
|
// services.
|
|
try await mqtt.shutdown()
|
|
} catch {
|
|
// If something fails, shutdown the mqtt client.
|
|
try await mqtt.shutdown()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension CliClient {
|
|
func setupRun(
|
|
eventLoopGroup: MultiThreadedEventLoopGroup = .init(numberOfThreads: 1),
|
|
loggerLabel: String = "dewpoint-controller",
|
|
options: Application.SharedOptions
|
|
) async throws -> (MQTTClient, Logger) {
|
|
var logger = Logger(label: loggerLabel)
|
|
let environment = try await makeEnvVars(options.envVarsRequest(logger: logger))
|
|
logger.logLevel = logLevel(environment)
|
|
let client = try makeClient(.init(
|
|
environment: environment,
|
|
eventLoopGroup: eventLoopGroup,
|
|
logger: logger
|
|
))
|
|
|
|
return (client, logger)
|
|
}
|
|
}
|