Files
swift-mqtt-dewpoint/Sources/DewPointController/RunCommand.swift
Michael Housh ce18c44363
Some checks failed
CI / Run Tests (push) Failing after 3m7s
feat: Working on cli client and tests
2024-11-17 22:23:44 -05:00

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