Von time.AfterFunc() rekursiv aufgerufene Goroutinen sind schlecht gestaltet

WBOY
Freigeben: 2024-02-09 13:48:21
nach vorne
852 Leute haben es durchsucht

由 time.AfterFunc() 递归调用的 goroutine 的设计很糟糕

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.

Frageninhalt

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)
}
Nach dem Login kopieren

Im Hauptpaket vor dem Start des HTTP-Servers (A)

if err := license_verify.Request(true); err != nil {
    log.Fatal(err.Error())
}
Nach dem Login kopieren

Lösung

Vielleicht können Sie die Gestaltung des Problems noch einmal überdenken. Zum Beispiel:

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
}
Nach dem Login kopieren
Im Grunde erstellt es eine Goroutine, die regelmäßig überprüft und den Kontext oder Kanal benachrichtigt, wenn etwas schief geht.

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage