PHP-Redakteur Xigua glaubt, dass der Satz „Das von time.AfterFunc() rekursiv aufgerufene Design von Goroutine ist sehr schlecht“ eine unvernünftige Designidee widerspiegelt. Bei der gleichzeitigen Programmierung kann der rekursive Aufruf von Goroutinen zu einem übermäßigen Ressourcenverbrauch und sogar zu Problemen wie Deadlocks und Speicherüberlauf führen. Daher sollten rekursive Aufrufe mit Vorsicht verwendet werden und andere Alternativen zur Lösung des Problems in Betracht gezogen werden, um die Leistung und Stabilität des Programms sicherzustellen. Beim Schreiben von Code sollten wir immer auf die Rationalität des Designs achten, um unnötige Probleme zu vermeiden.
Ich habe eine kleine http-Anwendung (A). Beim Start ruft es einen anderen http-Dienst (B) auf, um die Lizenz zu überprüfen. Wenn die Lizenz in Ordnung ist, wird der http-Server (A) gestartet. Wenn die Überprüfung fehlschlägt, tritt ein schwerwiegender Fehler auf und der Vorgang wird beendet
Lizenzprüfungen werden alle 24 Stunden durchgeführt
Wäre es ein schlechtes Design, alle 24 Stunden rekursiv eine neue Goroutine zu erstellen? Überprüfen Sie meinen Code unten. Wird die vorherige Goroutine geschlossen oder läuft sie weiter und dann rufen sich n Goroutinen gegenseitig auf und werden beendet?
Wird jede neue Goroutine von der Haupt-Goroutine oder von der untergeordneten Goroutine aufgerufen?Modul zur Lizenzüberprüfung. Ein Inspektionsdienst B
func Request(retry bool) error { // request and verify license (external http service) err := verify_license() if err != nil { return err } if retry { // Renew verification timeout (renew license every 24 hours) time.AfterFunc(LICENSE_TIMEOUT, func(){ request_retry() }) } return nil } func request_retry(){ for i := 0; i < LICENSE_RETRY; i++ { if err := v.Request(false); err == nil { break } time.Sleep(LICENSE_RETRY_TIMEOUT) } time.Sleep(LICENSE_TIMEOUT) v.Request(true) }
if err := license_verify.Request(true); err != nil { log.Fatal(err.Error()) }
func main() { if !checkLicense() { log.Fatal("license check failed") } srv := http.Server{} // ctx, cancel := context.WithCancel(context.Background()) defer cancel() go func() { for { select { case <-ctx.Done(): // in case you want to instal signal handlers etc return case <-time.After(24 * time.Hour): if !checkLicense() { cancel() // or srv.Shtdown, really depends on you } } } }() if err := srv.ListenAndServe(); err != nil { log.Fatal(err) } } func checkLicense() bool { // add retries per request here }
Wenn ich die Frage richtig verstehe, müssen Sie sie einfach halten. Ein Baustein besteht darin, eine Anfrage erneut zu versuchen, wenn sie fehlschlägt. Andernfalls gibt es einen 24-Stunden-Wiederholungsversuch. Die letzte Ebene besteht darin, auf die Prüfung zu reagieren, wenn diese fehlschlägt. Sie können Kontext, Kanal oder was auch immer Ihnen wirklich gefällt
verwenden
Das obige ist der detaillierte Inhalt vonVon time.AfterFunc() rekursiv aufgerufene Goroutinen sind schlecht gestaltet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!