ホームページ >バックエンド開発 >Golang >time.AfterFunc() によって再帰的に呼び出されるゴルーチンの設計が不十分である

time.AfterFunc() によって再帰的に呼び出されるゴルーチンの設計が不十分である

WBOY
WBOY転載
2024-02-09 13:48:21860ブラウズ

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

php エディタの Xigua は、「時間によって再帰的に呼び出される goroutine の設計。AfterFunc() は非常に悪いです。」という文は、不合理な設計思想を反映していると考えています。並行プログラミングでは、ゴルーチンを再帰的に呼び出すとリソースが過剰に消費され、さらにはデッドロックやメモリ オーバーフローなどの問題が発生する可能性があります。したがって、プログラムのパフォーマンスと安定性を確保するには、再帰呼び出しは慎重に使用する必要があり、問題を解決するための他の代替手段を検討する必要があります。コードを記述するときは、不要な問題を避けるために、設計の合理性に常に注意を払う必要があります。

質問内容

小規模な http アプリケーション (A) があります。起動時に、別の http サービス (B) を呼び出してライセンスを確認し、ライセンスに問題がない場合は、http サーバー (A) が起動します。検証が失敗すると、致命的なエラーが発生し、終了します。

ライセンスチェックは24時間ごとに実行されます

24 時間ごとに新しい goroutine を再帰的に作成するのは悪い設計とみなされますか?以下のコードを確認してください。前のゴルーチンが閉じられるか、それとも実行を継続するか。その後、n 個のゴルーチンが互いに呼び出して終了します。

新しい各ゴルーチンはメインのゴルーチンから呼び出されるのか、それとも子ゴルーチンから呼び出されるのか?

ライセンス検証モジュール。検査サービス B

リーリー

HTTPサーバー(A)が起動する前のメインパッケージ内

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)
}

解決策

問題の設計を再考できるかもしれません。例えば:### リーリー

基本的に、これが行うことは、定期的にチェックし、何か問題が発生した場合にコンテキストまたはチャネルに通知する goroutine を作成することです。

私が質問を正しく理解しているのであれば、単純に答えていただければ大丈夫です。構成要素の 1 つは、リクエストが失敗した場合にリクエストを再試行することです。それ以外の場合は、24 時間再試行されます。最後の層は、チェックが失敗した場合に反応します。コンテキスト、チャネル、または本当に好きなものを使用できます

以上がtime.AfterFunc() によって再帰的に呼び出されるゴルーチンの設計が不十分であるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。