From e80b31876c1e792a2adee113d17fd9f353697c60 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Wed, 13 Mar 2024 10:29:54 +0000 Subject: [PATCH] Add JobParameters that collates job parameters and id into one (#398) --- Sources/HummingbirdJobs/JobDefinition.swift | 5 ++ Sources/HummingbirdJobs/JobParameters.swift | 55 +++++++++++++++++++ .../HummingbirdJobsTests.swift | 20 +++++++ 3 files changed, 80 insertions(+) create mode 100644 Sources/HummingbirdJobs/JobParameters.swift diff --git a/Sources/HummingbirdJobs/JobDefinition.swift b/Sources/HummingbirdJobs/JobDefinition.swift index 4a75bc873..30307771a 100644 --- a/Sources/HummingbirdJobs/JobDefinition.swift +++ b/Sources/HummingbirdJobs/JobDefinition.swift @@ -18,6 +18,11 @@ public struct JobDefinition: Sendable { let maxRetryCount: Int let _execute: @Sendable (Parameters, JobContext) async throws -> Void + /// Initialize JobDefinition + /// - Parameters: + /// - id: Job identifier + /// - maxRetryCount: Maxiumum times this job will be retried if it fails + /// - execute: Closure that executes job public init(id: JobIdentifier, maxRetryCount: Int = 0, execute: @escaping @Sendable (Parameters, JobContext) async throws -> Void) { self.id = id self.maxRetryCount = maxRetryCount diff --git a/Sources/HummingbirdJobs/JobParameters.swift b/Sources/HummingbirdJobs/JobParameters.swift new file mode 100644 index 000000000..d6265e86d --- /dev/null +++ b/Sources/HummingbirdJobs/JobParameters.swift @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 2021-2024 the Hummingbird authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// Defines job parameters and identifier +public protocol JobParameters: Codable, Sendable { + /// Job type identifier + static var jobID: String { get } +} + +extension JobQueue { + /// Push Job onto queue + /// - Parameters: + /// - parameters: parameters for the job + /// - Returns: Identifier of queued job + @discardableResult public func push(_ parameters: Parameters) async throws -> Queue.JobID { + return try await self.push(id: .init(Parameters.jobID), parameters: parameters) + } + + /// Register job type + /// - Parameters: + /// - parameters: Job parameter type + /// - maxRetryCount: Maximum number of times job is retried before being flagged as failed + /// - execute: Job code + public func registerJob( + parameters: Parameters.Type = Parameters.self, + maxRetryCount: Int = 0, + execute: @escaping @Sendable ( + Parameters, + JobContext + ) async throws -> Void + ) { + self.registerJob(id: .init(Parameters.jobID), maxRetryCount: maxRetryCount, execute: execute) + } +} + +extension JobDefinition where Parameters: JobParameters { + /// Initialize JobDefinition + /// - Parameters: + /// - maxRetryCount: Maxiumum times this job will be retried if it fails + /// - execute: Closure that executes job + public init(maxRetryCount: Int = 0, execute: @escaping @Sendable (Parameters, JobContext) async throws -> Void) { + self.init(id: .init(Parameters.jobID), maxRetryCount: maxRetryCount, execute: execute) + } +} diff --git a/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift b/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift index 4f086d75d..3b9afe52e 100644 --- a/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift +++ b/Tests/HummingbirdJobsTests/HummingbirdJobsTests.swift @@ -164,6 +164,26 @@ final class HummingbirdJobsTests: XCTestCase { } } + func testJobParameters() async throws { + struct TestJobParameters: JobParameters { + static let jobID: String = "TestJobParameters" + let id: Int + let message: String + } + let expectation = XCTestExpectation(description: "TestJob.execute was called") + let jobQueue = JobQueue(.memory, numWorkers: 1, logger: Logger(label: "HummingbirdJobsTests")) + jobQueue.registerJob(parameters: TestJobParameters.self) { parameters, _ in + XCTAssertEqual(parameters.id, 23) + XCTAssertEqual(parameters.message, "Hello!") + expectation.fulfill() + } + try await self.testJobQueue(jobQueue) { + try await jobQueue.push(TestJobParameters(id: 23, message: "Hello!")) + + await self.wait(for: [expectation], timeout: 5) + } + } + /// Verify test job is cancelled when service group is cancelled func testShutdownJob() async throws { let jobIdentifer = JobIdentifier(#function)