2016-07-11 7 views
1

私はデータベースからJsonを返すメソッドを持っていますが、それは正しく動作しますが、同時実行しようとすると何も返されず、エラーも発生しません。たとえば、これは正しくGolangがメソッドを同時実行しようとしたときに何も返さない

func Listing_Expiration(w http.ResponseWriter, r *http.Request) { 

     db,err := sql.Open("DB_Connect") 

     if err != nil { 
      log.Fatal(err) 
      println(err) 
     } 



     var result string 

     errr := db.QueryRow("select json_build_object('Expiration', array_to_json(array_agg(t))) from (select fullname,ad_end from profiles where id=32)t").Scan(&result) 


     defer db.Close() 
     switch { 
     case errr != nil: 
      log.Fatal(errr) 


     } 


     fmt.Fprintf(w,result) 

} 

上記の方法が正しく動作し、データがブラウザに返され、その後、私は

func Listing_Expiration(w http.ResponseWriter, r *http.Request) { 
     go func(){ 

      db,err := sql.Open("DB_Connect") 

      if err != nil { 
       log.Fatal(err) 
       println(err) 
      } 



      var result string 

      errr := db.QueryRow("select json_build_object('Expiration', array_to_json(array_agg(t))) from (select fullname,ad_end from profiles where id=32)t").Scan(&result) 


      defer db.Close() 
      switch { 
      case errr != nil: 
       log.Fatal(errr) 


      } 


      fmt.Fprintf(w,result) 

     }() 
    } 

何も返さないだけ上記の非同期非同期(async)このメソッドをしようと取り組ん方法であり、私が変更したことは、Go func()をメソッドの中に追加して、非同期で他のすべてが同じになるようにすることです。私はチェックし、データベースは同じ内容を戻しているだけで、非同期がなぜ結果をブラウザに戻さないのか分かりません。

答えて

3

net/httpサーバーは、ハンドラが返されたときに応答を完了します。ハンドラが返った後に応答に書き込まれたものはすべて無視されます。

匿名関数がfmt.Fprintf(w,result)を実行する前に、ハンドラ関数Listing_Expirationが返されています。この問題を解決するには

sync.WaitGroupを使用します。

func Listing_Expiration(w http.ResponseWriter, r *http.Request) { 
    var wg sync.WaitGroup 
    wg.Add(1) 
    go func(){ 
    defer wg.Done() 
    // same code here as in question 
    }() 
    wg.Wait() 
} 

ネット/ HTTPサーバは、各接続のためのゴルーチンを開始し、それらのゴルーチンでハンドラを実行します。質問のコードが完全なハンドラであれば、別のゴルーチンを開始する理由はありません。

+0

完璧に機能しました。今はドキュメントを読むつもりです。基本的にブラウザに印刷するGoRoutineを使用するときは、常にWaitGoupを使用してください。 – user1591668

+1

アプリケーションがゴルーチンからの応答に書き込む場合、アプリケーションは何かをして、ハンドラがゴルーチンを待つことを保証する必要があります。これを行うには、WaitGroupsが便利な方法です。チャンネルを使用することもできます。レスポンスライターのレースを避けるには、通常、ハンドラーのゴルーチンからの応答に書き込むことが最善です。この例では問題にはなりませんが、アプリが2つのクエリを非同期に実行する場合どうなるかを検討してください。 –

+0

ありがとうございました。私はGoroutineハンドラからの応答を完全に書き直します。 – user1591668

関連する問題