Skip to content

Commit

Permalink
Update from Hummingbird Project Template (#41)
Browse files Browse the repository at this point in the history
* Update from hummingbird-project-template 572d468b2cabeca286314c5a35196bd42445c8ef

* run swift-format

* Remove .swiftformat

---------

Co-authored-by: adam-fowler <[email protected]>
Co-authored-by: Adam Fowler <[email protected]>
  • Loading branch information
3 people authored Nov 28, 2024
1 parent 68a54aa commit 5b31ced
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 138 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,12 @@ concurrency:

jobs:
validate:
runs-on: macOS-latest
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Install Dependencies
run: |
brew install mint
mint install NickLockwood/[email protected] --no-link
- name: run script
run: ./scripts/validate.sh
63 changes: 63 additions & 0 deletions .swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"version" : 1,
"indentation" : {
"spaces" : 4
},
"tabWidth" : 4,
"fileScopedDeclarationPrivacy" : {
"accessLevel" : "private"
},
"spacesAroundRangeFormationOperators" : false,
"indentConditionalCompilationBlocks" : false,
"indentSwitchCaseLabels" : false,
"lineBreakAroundMultilineExpressionChainComponents" : false,
"lineBreakBeforeControlFlowKeywords" : false,
"lineBreakBeforeEachArgument" : true,
"lineBreakBeforeEachGenericRequirement" : true,
"lineLength" : 150,
"maximumBlankLines" : 1,
"respectsExistingLineBreaks" : true,
"prioritizeKeepingFunctionOutputTogether" : true,
"multiElementCollectionTrailingCommas" : true,
"rules" : {
"AllPublicDeclarationsHaveDocumentation" : false,
"AlwaysUseLiteralForEmptyCollectionInit" : false,
"AlwaysUseLowerCamelCase" : false,
"AmbiguousTrailingClosureOverload" : true,
"BeginDocumentationCommentWithOneLineSummary" : false,
"DoNotUseSemicolons" : true,
"DontRepeatTypeInStaticProperties" : true,
"FileScopedDeclarationPrivacy" : true,
"FullyIndirectEnum" : true,
"GroupNumericLiterals" : true,
"IdentifiersMustBeASCII" : true,
"NeverForceUnwrap" : false,
"NeverUseForceTry" : false,
"NeverUseImplicitlyUnwrappedOptionals" : false,
"NoAccessLevelOnExtensionDeclaration" : true,
"NoAssignmentInExpressions" : true,
"NoBlockComments" : true,
"NoCasesWithOnlyFallthrough" : true,
"NoEmptyTrailingClosureParentheses" : true,
"NoLabelsInCasePatterns" : true,
"NoLeadingUnderscores" : false,
"NoParensAroundConditions" : true,
"NoVoidReturnOnFunctionSignature" : true,
"OmitExplicitReturns" : true,
"OneCasePerLine" : true,
"OneVariableDeclarationPerLine" : true,
"OnlyOneTrailingClosureArgument" : true,
"OrderedImports" : true,
"ReplaceForEachWithForLoop" : true,
"ReturnVoidInsteadOfEmptyTuple" : true,
"UseEarlyExits" : false,
"UseExplicitNilCheckInConditions" : false,
"UseLetInEveryBoundCaseVariable" : false,
"UseShorthandTypeNames" : true,
"UseSingleLinePropertyGetter" : false,
"UseSynthesizedInitializer" : false,
"UseTripleSlashForDocumentationComments" : true,
"UseWhereClausesInForLoops" : false,
"ValidateDocumentationComments" : false
}
}
26 changes: 0 additions & 26 deletions .swiftformat

This file was deleted.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ The main development branch of the repository is `main`.

### Formatting

We use Nick Lockwood's SwiftFormat for formatting code. PRs will not be accepted if they haven't be formatted. The current version of SwiftFormat we are using is v0.53.10.
We use Apple's swift-format for formatting code. PRs will not be accepted if they haven't be formatted.
13 changes: 8 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ let package = Package(
name: "swift-jobs",
platforms: [.macOS(.v14), .iOS(.v17), .tvOS(.v17)],
products: [
.library(name: "Jobs", targets: ["Jobs"]),
.library(name: "Jobs", targets: ["Jobs"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.0"),
Expand All @@ -34,9 +34,12 @@ let package = Package(
swiftSettings: swiftSettings
),
// test targets
.testTarget(name: "JobsTests", dependencies: [
.byName(name: "Jobs"),
.product(name: "Atomics", package: "swift-atomics"),
]),
.testTarget(
name: "JobsTests",
dependencies: [
.byName(name: "Jobs"),
.product(name: "Atomics", package: "swift-atomics"),
]
),
]
)
26 changes: 15 additions & 11 deletions Sources/Jobs/JobMetricsHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ internal enum JobMetricsHelper {
// with something like count(swif_jobs_meter{status="processing"}
// unless on(jobID) (swif_jobs_meter{status="queued"})
// or (swif_jobs_meter{status="completed")) or vector(0)
Meter(label: JobMetricsHelper.meterLabel, dimensions: [
("status", JobMetricsHelper.JobStatus.completed.rawValue),
("jobID", jobID),
]).increment()
Meter(
label: JobMetricsHelper.meterLabel,
dimensions: [
("status", JobMetricsHelper.JobStatus.completed.rawValue),
("jobID", jobID),
]
).increment()

if retrying {
Counter(
Expand All @@ -66,15 +69,16 @@ internal enum JobMetricsHelper {
return
}

let jobStatus: JobStatus = if let error {
if error is CancellationError {
.cancelled
let jobStatus: JobStatus =
if let error {
if error is CancellationError {
.cancelled
} else {
.failed
}
} else {
.failed
.succeeded
}
} else {
.succeeded
}

let dimensions: [(String, String)] = [
("name", name),
Expand Down
14 changes: 10 additions & 4 deletions Sources/Jobs/JobParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ extension JobParameters {
}

/// Added so it is possible to push JobParameters referenced as Existentials to a Job queue
@discardableResult public func push<Queue: JobQueueDriver>(to jobQueue: JobQueue<Queue>, options: JobOptions = .init()) async throws -> Queue.JobID {
return try await jobQueue.push(self, options: options)
@discardableResult public func push<Queue: JobQueueDriver>(
to jobQueue: JobQueue<Queue>,
options: JobOptions = .init()
) async throws -> Queue.JobID {
try await jobQueue.push(self, options: options)
}
}

Expand All @@ -36,8 +39,11 @@ extension JobQueue {
/// - parameters: parameters for the job
/// - options: JobOptions
/// - Returns: Identifier of queued job
@discardableResult public func push<Parameters: JobParameters>(_ parameters: Parameters, options: JobOptions = .init()) async throws -> Queue.JobID {
return try await self.push(id: Parameters.jobID, parameters: parameters, options: options)
@discardableResult public func push<Parameters: JobParameters>(
_ parameters: Parameters,
options: JobOptions = .init()
) async throws -> Queue.JobID {
try await self.push(id: Parameters.jobID, parameters: parameters, options: options)
}

/// Register job type
Expand Down
11 changes: 7 additions & 4 deletions Sources/Jobs/JobQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,13 @@ public struct JobQueue<Queue: JobQueueDriver>: Service {
let buffer = try self.queue.encode(id: id, parameters: parameters)
let jobName = id.name
let id = try await self.queue.push(buffer, options: options)
Meter(label: JobMetricsHelper.meterLabel, dimensions: [
("status", JobMetricsHelper.JobStatus.queued.rawValue),
("jobID", id.description),
]).increment()
Meter(
label: JobMetricsHelper.meterLabel,
dimensions: [
("status", JobMetricsHelper.JobStatus.queued.rawValue),
("jobID", id.description),
]
).increment()
self.logger.debug(
"Pushed Job",
metadata: ["JobID": .stringConvertible(id), "JobName": .string(jobName)]
Expand Down
77 changes: 49 additions & 28 deletions Sources/Jobs/JobQueueHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,30 @@ final class JobQueueHandler<Queue: JobQueueDriver>: Sendable {
let startTime = DispatchTime.now().uptimeNanoseconds
logger[metadataKey: "JobID"] = .stringConvertible(queuedJob.id)
// Decrement the current queue by 1
Meter(label: JobMetricsHelper.meterLabel, dimensions: [
("status", JobMetricsHelper.JobStatus.queued.rawValue),
("jobID", queuedJob.id.description),
]).decrement()

Meter(label: JobMetricsHelper.meterLabel, dimensions: [
("status", JobMetricsHelper.JobStatus.processing.rawValue),
("jobID", queuedJob.id.description),
]).increment()
Meter(
label: JobMetricsHelper.meterLabel,
dimensions: [
("status", JobMetricsHelper.JobStatus.queued.rawValue),
("jobID", queuedJob.id.description),
]
).decrement()

defer {
Meter(label: JobMetricsHelper.meterLabel, dimensions: [
Meter(
label: JobMetricsHelper.meterLabel,
dimensions: [
("status", JobMetricsHelper.JobStatus.processing.rawValue),
("jobID", queuedJob.id.description),
]).decrement()
]
).increment()

defer {
Meter(
label: JobMetricsHelper.meterLabel,
dimensions: [
("status", JobMetricsHelper.JobStatus.processing.rawValue),
("jobID", queuedJob.id.description),
]
).decrement()
}

let job: any JobInstanceProtocol
Expand All @@ -92,18 +101,24 @@ final class JobQueueHandler<Queue: JobQueueDriver>: Sendable {
} catch let error as JobQueueError where error == .unrecognisedJobId {
logger.debug("Failed to find Job with ID while decoding")
try await self.queue.failed(jobId: queuedJob.id, error: error)
Meter(label: JobMetricsHelper.discardedMeter, dimensions: [
("reason", "INVALID_JOB_ID"),
("jobID", queuedJob.id.description),
]).increment()
Meter(
label: JobMetricsHelper.discardedMeter,
dimensions: [
("reason", "INVALID_JOB_ID"),
("jobID", queuedJob.id.description),
]
).increment()
return
} catch {
logger.debug("Job failed to decode")
try await self.queue.failed(jobId: queuedJob.id, error: JobQueueError.decodeJobFailed)
Meter(label: JobMetricsHelper.discardedMeter, dimensions: [
("reason", "DECODE_FAILED"),
("jobID", queuedJob.id.description),
]).increment()
Meter(
label: JobMetricsHelper.discardedMeter,
dimensions: [
("reason", "DECODE_FAILED"),
("jobID", queuedJob.id.description),
]
).increment()
return
}
logger[metadataKey: "JobName"] = .string(job.name)
Expand Down Expand Up @@ -163,21 +178,27 @@ final class JobQueueHandler<Queue: JobQueueDriver>: Sendable {

// Guard against negative queue values, this is needed because we call
// the job queue directly in the retrying step
Meter(label: JobMetricsHelper.meterLabel, dimensions: [
("status", JobMetricsHelper.JobStatus.queued.rawValue),
("jobID", newJobId.description),
]).increment()
Meter(
label: JobMetricsHelper.meterLabel,
dimensions: [
("status", JobMetricsHelper.JobStatus.queued.rawValue),
("jobID", newJobId.description),
]
).increment()

JobMetricsHelper.updateMetrics(
for: job.name,
jobID: queuedJob.id.description,
startTime: startTime,
retrying: true
)
logger.debug("Retrying Job", metadata: [
"attempts": .stringConvertible(attempts),
"delayedUntil": .stringConvertible(delay),
])
logger.debug(
"Retrying Job",
metadata: [
"attempts": .stringConvertible(attempts),
"delayedUntil": .stringConvertible(delay),
]
)
return
}
logger.debug("Finished Job")
Expand Down
4 changes: 2 additions & 2 deletions Sources/Jobs/JobRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct JobRegistry: Sendable {
}

func decode(_ buffer: ByteBuffer) throws -> any JobInstanceProtocol {
return try JSONDecoder().decode(AnyDecodableJob.self, from: buffer, userInfoConfiguration: self).job
try JSONDecoder().decode(AnyDecodableJob.self, from: buffer, userInfoConfiguration: self).job
}

func decode(jobName: String, from decoder: Decoder) throws -> any JobInstanceProtocol {
Expand All @@ -48,5 +48,5 @@ struct JobRegistry: Sendable {
return try jobDefinitionBuilder(decoder)
}

let builderTypeMap: NIOLockedValueBox < [String: @Sendable (Decoder) throws -> any JobInstanceProtocol]> = .init([:])
let builderTypeMap: NIOLockedValueBox<[String: @Sendable (Decoder) throws -> any JobInstanceProtocol]> = .init([:])
}
2 changes: 1 addition & 1 deletion Sources/Jobs/MemoryJobQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public final class MemoryQueue: JobQueueDriver {
/// - options: Job options
/// - Returns: Job ID
@discardableResult public func push(_ buffer: ByteBuffer, options: JobOptions) async throws -> JobID {
return try await self.queue.push(buffer, options: options)
try await self.queue.push(buffer, options: options)
}

public func finished(jobId: JobID) async throws {
Expand Down
15 changes: 8 additions & 7 deletions Sources/Jobs/Scheduler/JobSchedule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,16 @@ public struct JobSchedule: MutableCollection, Sendable {
}

func nextJob() -> (offset: Int, element: Element)? {
return self.lazy.enumerated().min(by: { $0.element.nextScheduledDate < $1.element.nextScheduledDate })
self.lazy.enumerated().min(by: { $0.element.nextScheduledDate < $1.element.nextScheduledDate })
}

mutating func updateNextScheduledDate(jobIndex: Int) {
let dateFrom: Date = switch self.self[jobIndex].accuracy {
case .latest: .now
case .all: self[jobIndex].nextScheduledDate
default: .now
}
let dateFrom: Date =
switch self.self[jobIndex].accuracy {
case .latest: .now
case .all: self[jobIndex].nextScheduledDate
default: .now
}
if let nextScheduledDate = self[jobIndex].schedule.nextDate(after: dateFrom) {
self[jobIndex].nextScheduledDate = nextScheduledDate
} else {
Expand Down Expand Up @@ -213,7 +214,7 @@ extension JobSchedule {
public var endIndex: Index { self.elements.endIndex }
/// Access element at specific position
public subscript(_ index: Index) -> Element {
get { return self.elements[index] }
get { self.elements[index] }
set { self.elements[index] = newValue }
}

Expand Down
Loading

0 comments on commit 5b31ced

Please sign in to comment.