-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
ScheduledJob.swift
52 lines (46 loc) · 1.61 KB
/
ScheduledJob.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import NIOCore
import Foundation
import Logging
/// Describes a job that can be scheduled and repeated
public protocol ScheduledJob {
var name: String { get }
/// The method called when the job is run
/// - Parameter context: A `JobContext` that can be used
func run(context: QueueContext) -> EventLoopFuture<Void>
}
extension ScheduledJob {
public var name: String { "\(Self.self)" }
}
class AnyScheduledJob {
let job: ScheduledJob
let scheduler: ScheduleBuilder
init(job: ScheduledJob, scheduler: ScheduleBuilder) {
self.job = job
self.scheduler = scheduler
}
}
extension AnyScheduledJob {
struct Task {
let task: RepeatedTask
let done: EventLoopFuture<Void>
}
func schedule(context: QueueContext) -> Task? {
context.logger.trace("Beginning the scheduler process")
guard let date = self.scheduler.nextDate() else {
context.logger.debug("No date scheduled for \(self.job.name)")
return nil
}
context.logger.debug("Scheduling \(self.job.name) to run at \(date)")
let promise = context.eventLoop.makePromise(of: Void.self)
let task = context.eventLoop.scheduleRepeatedTask(
initialDelay: .microseconds(Int64(date.timeIntervalSinceNow * 1_000_000)),
delay: .seconds(0)
) { task in
// always cancel
task.cancel()
context.logger.trace("Running the scheduled job \(self.job.name)")
self.job.run(context: context).cascade(to: promise)
}
return .init(task: task, done: promise.futureResult)
}
}