gpt4 book ai didi

go - 在 Web 应用程序中运行计划任务

转载 作者:数据小太阳 更新时间:2023-10-29 03:30:45 28 4
gpt4 key购买 nike

我想每 5 分钟运行一次任务来更新我网站上的统计数据而不阻塞 HTTP 服务器。

我刚刚添加了带有工作人员示例的基本 HTTP 服务器逻辑。如果我像这样添加多个任务,这是否被认为是不好的做法,还是有更好的方法?

package main

import (
"fmt"
"net/http"
"time"
)

func Home(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home page")
}

func schedule(f func(), interval time.Duration) *time.Ticker {
ticker := time.NewTicker(interval)
go func() {
for range ticker.C {
f()
}
}()
return ticker
}

func longRunningTask() {
fmt.Println("Long running task")
}

func main() {
schedule(longRunningTask, time.Second*5)

http.HandleFunc("/", Home)
http.ListenAndServe("127.0.0.1:8080", nil)
}

最佳答案

您的实现与 Go 中计划的作业/任务非常相似。有一些类似 cron 的库可以让您更好地控制任务,但在大多数情况下,一个带有循环的简单 goroutine 就足够了。

以下是根据您的需求增加复杂性的更多示例:


永远运行一个任务,每次运行之间等待 5 秒。无法停止且不考虑任务的运行时间。这是最简单的形式,也是最常见的形式。

go func() {
for {
task()
<-time.After(5 * time.Second)
}
}()

和以前一样,除了现在有一个 channel 可以停止任务,如果我们想的话。虽然您的实现允许您通过 Stop() 方法停止任务,但 goroutine 将保持打开状态,因为 channel 永远不会关闭(因此会泄漏内存)。

// Includes a channel to stop the task if needed.
quit := make(chan bool, 1)

go func() {
task()

for {
select {
case <-quit:
return
case <-time.After(5 * time.Second):
task()
}
}
}()

// To stop the task
quit <- true

这是三者中最稳健的解决方案。任务可以随时停止,它还会考虑任务在等待再次运行时运行了多长时间。在前面的示例中,如果任务运行需要 1 秒,而您又等待了 5 秒,则相对于任务开始的时间,您的间隔实际上是 6 秒。

此解决方案实际上仅适用于运行时间非常长的任务,或者如果您的任务以恒定间隔运行至关重要。如果任务必须以恒定的时间间隔运行,那么您需要考虑 time.After() 将至少等待您提供的持续时间这一事实——它最终可能会等待稍长的时间,如果CPU 正忙于其他进程/goroutines。

// Calls `fn` and then waits so the total elapsed time is `interval`
func runAndWait(interval time.Duration, fn func()) {
earlier := time.Now()
fn()
diff := time.Now().Sub(earlier)
<-time.After(interval - diff)
}

quit := make(chan bool, 1)

go func() {
// The total time to run one iteration of the task
interval := 5 * time.Second

for {
select {
case <-quit:
return
default:
runAndWait(interval, task)
}
}
}()

关于go - 在 Web 应用程序中运行计划任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57682902/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com