L'éditeur PHP Xigua estime que la phrase "La conception de goroutine appelée récursivement par time.AfterFunc() est très mauvaise" reflète une idée de conception déraisonnable. En programmation simultanée, l'appel récursif de goroutines peut entraîner une consommation excessive de ressources, et même provoquer des problèmes tels qu'un blocage et un débordement de mémoire. Par conséquent, les appels récursifs doivent être utilisés avec prudence et d'autres alternatives pour résoudre le problème doivent être envisagées afin de garantir les performances et la stabilité du programme. Lors de l’écriture du code, nous devons toujours prêter attention à la rationalité de la conception pour éviter des problèmes inutiles.
J'ai une petite application http (A). Au démarrage, il appelle un autre service http (B) pour vérifier la licence et si la licence est OK, le serveur http (A) démarre. Si la vérification échoue, une erreur fatale se produira et se terminera
Les contrôles de licence sont effectués toutes les 24 heures
Créer récursivement une nouvelle goroutine toutes les 24 heures serait-il considéré comme une mauvaise conception ? Vérifiez mon code ci-dessous. La goroutine précédente sera-t-elle fermée ou continuera-t-elle à s'exécuter, puis n goroutines s'appelleront et se termineront ?
Chaque nouvelle goroutine est-elle appelée depuis la goroutine principale ou depuis la goroutine enfant ?Module de vérification de licence. Un service d'inspection 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 }
Si je comprends bien la question, il vous suffit de rester simple. Un élément de base consiste à réessayer une demande si elle échoue. Sinon, il y a une nouvelle tentative de 24 heures. La dernière couche consiste à réagir à la vérification si elle échoue. Vous pouvez utiliser le contexte, le canal ou tout ce que vous aimez vraiment
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!