在 Vapor 请求期间调用的计时器从不触发

Timer called during Vapor request never fires

在 Vapor 的请求上下文中创建计时器是否存在任何问题?我需要触发在用户启动流程后几分钟发生的操作。到目前为止,当我调用执行此操作的例程时,我得到确认设置计时器的代码具有 运行。但是计时器和对主 DispatchQueue 的调用都不会触发。 调用设置的方法随后立即将用户重定向到另一个端点,我想知道这是否是原因。

func startTournament(req: Request) -> EventLoopFuture<Response> {
    let uId : UUID = req.auth.get(User.self)!.id!
    var tourn : Tournament?
    return User.query(on: req.db)
        .with(\.$tournament)  { [=10=].with(\.$invitations)}
        .filter(\.$id == uId)
        .first().flatMap { u  in
            tourn = u!.tournament!
            Tournament.addTournamentTimer(tourn!)

是调用设置的代码。

这是调用的方法,打印语句执行:

static func addTournamentTimer(_ tourn : Tournament) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
        print("Timer fired!")
    }
    let timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { timer in
        print("Timer fired!")
    }
    print("adding timer for tournament \(tourn.name)")
}

我不想使用 DispatchQueue 方法,但我尝试包含它以查看它是否有效。好像没有。我对使用定时器还很陌生,但我有相当多的功能可以在客户端应用程序中使用定时器,所以我很能够在其他地方找到它们。同样,我假设我对异步不太清楚 请求,和/或计时器在重定向发生时被丢弃?

在服务器端设置定时器的正确方法是使用 NIO 而不是 GCD。

拿一个 eventLoop 并检查其 schedule... 方法以选择适合您的情况的方法。

这是您使用 NIO 的方法示例:

static func addTournamentTimer(_ tourn : Tournament, on req: Request) {
    req.eventLoop.scheduleTask(deadline: NIODeadline.now() + .seconds(5)) {
        print("Timer fired!")
    }
    print("adding timer for tournament \(tourn.name)")
}