@@ -65,25 +65,15 @@ public final class PostgresJobQueue: JobQueueDriver, CancellableJobQueue, Resuma
65
65
case highest = 4
66
66
}
67
67
/// Lowest priority
68
- public static func lowest( ) -> JobPriority {
69
- JobPriority ( rawValue: . lowest)
70
- }
68
+ public static let lowest : JobPriority = JobPriority ( rawValue: . lowest)
71
69
/// Lower priority
72
- public static func lower( ) -> JobPriority {
73
- JobPriority ( rawValue: . lower)
74
- }
70
+ public static let lower : JobPriority = JobPriority ( rawValue: . lower)
75
71
/// Normal is the default priority
76
- public static func normal( ) -> JobPriority {
77
- JobPriority ( rawValue: . normal)
78
- }
72
+ public static let normal : JobPriority = JobPriority ( rawValue: . normal)
79
73
/// Higher priority
80
- public static func higher( ) -> JobPriority {
81
- JobPriority ( rawValue: . higher)
82
- }
74
+ public static let higher : JobPriority = JobPriority ( rawValue: . higher)
83
75
/// Higgest priority
84
- public static func highest( ) -> JobPriority {
85
- JobPriority ( rawValue: . highest)
86
- }
76
+ public static let highest : JobPriority = JobPriority ( rawValue: . highest)
87
77
}
88
78
89
79
/// Options for job pushed to queue
@@ -92,26 +82,35 @@ public final class PostgresJobQueue: JobQueueDriver, CancellableJobQueue, Resuma
92
82
public var delayUntil : Date
93
83
/// Priority for this job
94
84
public var priority : JobPriority
85
+ /// Deduplication Key
86
+ public var deduplicationKey : String
95
87
96
88
/// Default initializer for JobOptions
97
89
public init ( ) {
98
90
self . delayUntil = . now
99
- self . priority = . normal( )
91
+ self . priority = . normal
92
+ self . deduplicationKey = UUID ( ) . uuidString
100
93
}
101
94
102
95
/// Initializer for JobOptions
103
96
/// - Parameter delayUntil: Whether job execution should be delayed until a later date
104
97
public init ( delayUntil: Date ? ) {
105
98
self . delayUntil = delayUntil ?? . now
106
- self . priority = . normal( )
99
+ self . priority = . normal
100
+ self . deduplicationKey = UUID ( ) . uuidString
107
101
}
108
102
109
103
/// Initializer for JobOptions
110
104
/// - Parameter delayUntil: Whether job execution should be delayed until a later date
111
105
/// - Parameter priority: The priority for a job
112
- public init ( delayUntil: Date = . now, priority: JobPriority = . normal( ) ) {
106
+ public init (
107
+ delayUntil: Date = . now,
108
+ priority: JobPriority = . normal,
109
+ deduplicationKey: String = UUID ( ) . uuidString
110
+ ) {
113
111
self . delayUntil = delayUntil
114
112
self . priority = priority
113
+ self . deduplicationKey = deduplicationKey
115
114
}
116
115
}
117
116
@@ -291,9 +290,28 @@ public final class PostgresJobQueue: JobQueueDriver, CancellableJobQueue, Resuma
291
290
/// - Returns: Identifier of queued job
292
291
@discardableResult public func push< Parameters: JobParameters > ( _ jobRequest: JobRequest < Parameters > , options: JobOptions ) async throws -> JobID {
293
292
let jobID = JobID ( )
294
- try await self . client. withTransaction ( logger: self . logger) { connection in
295
- try await self . add ( jobID: jobID, jobRequest: jobRequest, queueName: configuration. queueName, connection: connection)
296
- try await self . addToQueue ( jobID: jobID, queueName: configuration. queueName, options: options, connection: connection)
293
+ let insertedJob = try await self . client. withTransaction ( logger: self . logger) { connection in
294
+ let id = try await self . add (
295
+ jobID: jobID,
296
+ jobRequest: jobRequest,
297
+ queueName: configuration. queueName,
298
+ deduplicationKey: options. deduplicationKey,
299
+ connection: connection
300
+ )
301
+ // We should never have and empty job id
302
+ let insertedJobID = id ?? jobID
303
+ try await self . addToQueue (
304
+ jobID: insertedJobID,
305
+ queueName: configuration. queueName,
306
+ options: options,
307
+ connection: connection
308
+ )
309
+ return insertedJobID
310
+ }
311
+
312
+ if insertedJob != jobID {
313
+ // TODO: introduce a duplicate jobID error
314
+ throw JobQueueError ( code: . unrecognisedJobId, jobName: Parameters . jobName)
297
315
}
298
316
return jobID
299
317
}
@@ -452,14 +470,23 @@ public final class PostgresJobQueue: JobQueueDriver, CancellableJobQueue, Resuma
452
470
}
453
471
}
454
472
455
- func add< Parameters> ( jobID: JobID , jobRequest: JobRequest < Parameters > , queueName: String , connection: PostgresConnection ) async throws {
456
- try await connection. query (
473
+ func add< Parameters> (
474
+ jobID: JobID ,
475
+ jobRequest: JobRequest < Parameters > ,
476
+ queueName: String ,
477
+ deduplicationKey: String ,
478
+ connection: PostgresConnection
479
+ ) async throws -> JobID ? {
480
+ let stream = try await connection. query (
457
481
"""
458
- INSERT INTO swift_jobs.jobs (id, job, status, queue_name)
459
- VALUES ( \( jobID) , \( jobRequest) , \( Status . pending) , \( queueName) )
482
+ INSERT INTO swift_jobs.jobs (id, job, status, queue_name, unique_key)
483
+ VALUES ( \( jobID) , \( jobRequest) , \( Status . pending) , \( queueName) , \( deduplicationKey) )
484
+ ON CONFLICT DO NOTHING
485
+ RETURNING id
460
486
""" ,
461
487
logger: self . logger
462
488
)
489
+ return try await stream. decode ( JobID . self) . first ( where: { _ in true } )
463
490
}
464
491
// TODO: maybe add a new column colum for attempt so far after PR https://github.com/hummingbird-project/swift-jobs/pull/63 is merged?
465
492
func updateJob( id: JobID , buffer: ByteBuffer , connection: PostgresConnection ) async throws {
0 commit comments