diff --git a/Package.swift b/Package.swift index 79fd2cb..53a6fda 100755 --- a/Package.swift +++ b/Package.swift @@ -8,8 +8,8 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/vapor/vapor", from: "4.0.0"), - .package(url: "https://github.com/christophhagen/Clairvoyant", from: "0.9.0"), - .package(url: "https://github.com/christophhagen/ClairvoyantVapor", from: "0.2.0"), + .package(url: "https://github.com/christophhagen/Clairvoyant", from: "0.11.2"), + .package(url: "https://github.com/christophhagen/ClairvoyantVapor", from: "0.4.0"), .package(url: "https://github.com/christophhagen/ClairvoyantBinaryCodable", from: "0.3.0"), ], targets: [ diff --git a/Sources/App/CapServer.swift b/Sources/App/CapServer.swift index dd49704..a88f4a7 100644 --- a/Sources/App/CapServer.swift +++ b/Sources/App/CapServer.swift @@ -81,7 +81,7 @@ final class CapServer { caps.reduce(0) { $0 + $1.value.count } } - init(in folder: URL) async { + init(in folder: URL) { self.imageFolder = folder.appendingPathComponent("images") self.thumbnailFolder = folder.appendingPathComponent("thumbnails") self.gridCountFile = folder.appendingPathComponent("count.js") @@ -95,15 +95,15 @@ final class CapServer { changedImageEntryDateFormatter.dateFormat = "yy-MM-dd-HH-mm-ss" // Metric initializers only fail if observer is missing or ID is duplicate - self.capCountMetric = try! await .init("caps.count", + self.capCountMetric = .init("caps.count", name: "Number of caps", description: "The total number of caps in the database") - self.imageCountMetric = try! await .init("caps.images", + self.imageCountMetric = .init("caps.images", name: "Total images", description: "The total number of images for all caps") - self.classifierMetric = try! await .init("caps.classifier", + self.classifierMetric = .init("caps.classifier", name: "Classifier Version", description: "The current version of the image classifier") } diff --git a/Sources/App/EventLoopScheduler.swift b/Sources/App/EventLoopScheduler.swift new file mode 100644 index 0000000..3997c05 --- /dev/null +++ b/Sources/App/EventLoopScheduler.swift @@ -0,0 +1,34 @@ +import Foundation +import Clairvoyant +import Vapor +import NIOCore + +final class EventLoopScheduler { + + private let backgroundGroup: EventLoopGroup + + init(numberOfThreads: Int = 2) { + backgroundGroup = MultiThreadedEventLoopGroup(numberOfThreads: numberOfThreads) + } + + func next() -> EventLoop { + backgroundGroup.next() + } + + func provider() -> NIOEventLoopGroupProvider { + return .shared(backgroundGroup) + } + + func shutdown() { + backgroundGroup.shutdownGracefully { _ in + + } + } +} + +extension EventLoopScheduler: AsyncScheduler { + + func schedule(asyncJob: @escaping @Sendable () async throws -> Void) { + _ = backgroundGroup.any().makeFutureWithTask(asyncJob) + } +} diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 93bb7cb..52ca1d6 100755 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -6,6 +6,8 @@ import ClairvoyantBinaryCodable private var provider: VaporMetricProvider! +private let asyncScheduler = EventLoopScheduler() + public func configure(_ app: Application) async throws { let resourceDirectory = URL(fileURLWithPath: app.directory.resourcesDirectory) @@ -17,7 +19,7 @@ public func configure(_ app: Application) async throws { let monitor = MetricObserver(logFileFolder: config.logURL, logMetricId: "caps.log") MetricObserver.standard = monitor - let status = try await Metric("caps.status", + let status = Metric("caps.status", name: "Status", description: "The general status of the service") try await status.update(.initializing) @@ -25,9 +27,10 @@ public func configure(_ app: Application) async throws { app.http.server.configuration.port = config.port app.routes.defaultMaxBodySize = .init(stringLiteral: config.maxBodySize) - let server = await CapServer(in: URL(fileURLWithPath: publicDirectory)) + let server = CapServer(in: URL(fileURLWithPath: publicDirectory)) provider = .init(observer: monitor, accessManager: config.writers) + provider.asyncScheduler = asyncScheduler provider.registerRoutes(app) if config.serveFiles { @@ -52,5 +55,7 @@ func log(_ message: String) { print(message) return } - observer.log(message) + asyncScheduler.schedule { + await observer.log(message) + } }