Gibt es eine Möglichkeit, sich wiederholende Hintergrundaufgaben in Go auszuführen? Ich denke an so etwas wie Timer.schedule(task, delay, period)
in Java. Ich weiß, dass ich das mit einer Goroutine machen kann und Time.sleep()
, aber ich möchte etwas, das leicht zu stoppen ist.
Folgendes habe ich bekommen, sehe aber für mich hässlich aus. Gibt es einen saubereren / besseren Weg?
func oneWay() {
var f func()
var t *time.Timer
f = func () {
fmt.Println("doing stuff")
t = time.AfterFunc(time.Duration(5) * time.Second, f)
}
t = time.AfterFunc(time.Duration(5) * time.Second, f)
defer t.Stop()
//simulate doing stuff
time.Sleep(time.Minute)
}
t := time.Tick(time.Duration(period) * time.Second)
wo Zeitraum ist einint
Antworten:
Die Funktion erstellt
time.NewTicker
einen Kanal, der eine periodische Nachricht sendet, und bietet eine Möglichkeit, diese zu stoppen. Verwenden Sie es so etwas (ungetestet):Sie können den Worker stoppen, indem Sie den
quit
Kanal schließen :close(quit)
.quelle
do stuff
eine Go-Routine ausführen, oder der nächste Worker würde sofort ausgeführt (wenn er mehr als 5 Sekunden benötigt).close(quit)
wenn Sie den Scheduler stoppen möchten.go func() { /*do stuff */ }()
.Wie wäre es mit so etwas
Spielplatz
quelle
time.Ticker
ist besser als dort,time.After
wo Sie die Aufgabe lieber im Zeitplan halten möchten, als eine willkürliche Lücke zwischen den Ausführungen.If efficiency is a concern, use NewTimer
Wenn Sie sich nicht für das Tick-Shifting interessieren (abhängig davon, wie lange es zuvor bei jeder Ausführung gedauert hat) und keine Kanäle verwenden möchten, können Sie die native Bereichsfunktion verwenden.
dh
Spielplatz
quelle
Schauen Sie sich diese Bibliothek an: https://github.com/robfig/cron
Beispiel wie folgt:
quelle
Eine umfassendere Antwort auf diese Frage könnte den in Occam häufig verwendeten Lego-Brick-Ansatz berücksichtigen, der der Java-Community über JCSP angeboten wird . Es gibt eine sehr gute Präsentation von Peter Welch zu dieser Idee.
Dieser Plug-and-Play-Ansatz wird direkt in Go übersetzt, da Go dieselben Grundlagen für den kommunizierenden sequentiellen Prozess verwendet wie Occam.
Wenn Sie sich wiederholende Aufgaben entwerfen, können Sie Ihr System als Datenflussnetzwerk aus einfachen Komponenten (als Goroutinen) aufbauen, die Ereignisse (dh Nachrichten oder Signale) über Kanäle austauschen.
Dieser Ansatz ist kompositorisch: Jede Gruppe kleiner Komponenten kann sich ad infinitum als größere Komponente verhalten. Dies kann sehr leistungsfähig sein, da komplexe gleichzeitige Systeme aus leicht verständlichen Bausteinen bestehen.
Fußnote: In Welchs Präsentation verwendet er die Occam-Syntax für Kanäle, das heißt ! und ? und diese entsprechen direkt ch <- und <-ch in Go.
quelle
Ich benutze den folgenden Code:
Es ist einfacher und funktioniert gut für mich.
quelle
Wenn Sie es in jedem Moment stoppen möchten, ticken Sie
Wenn Sie nicht aufhören wollen, es tick :
quelle