2016-05-25 13 views
0

私はGoスクリプトを作成して、できるだけ多くのhttpリクエストをAPIから取得します。Golang、HTTPリクエストでnilを返します。

soundcloud.GetUser(i)の行でnilポインタ参照を取得していますが、worker()を複数のgoroutine(正確には200以上)で呼び出すと、

これは私が正確になっているエラーです。

goroutine 28 [running]: 
runtime.panic(0x75fca0, 0x98cf13) 
/usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5 www.github.com/Juanvulcano/gosoundcloud%2egit.processAndUnmarshalResponses(0x0, 0x7f1d338e9fd0, 0xc209467a10, 0x780a60, 0xc20809c300, 0x0, 0x0) 
     /home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/gosoundcloud.go:31 +0x413 
www.github.com/Juanvulcano/gosoundcloud%2egit.(*SoundcloudApi).GetUser(0xc208040520, 0x2, 0x7f1d41e81f40, 0x0, 0x0) 
    /home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/soundcloud.go:295 +0x1b1 
main.worker() 
    /home/maker/go/src/GoBot/GoBot.go:28 +0xdd 
created by main.main 
    /home/maker/go/src/GoBot/GoBot.go:71 +0x55d 

ここで私のコードの重要な部分を付けています。

機能で
func worker() { 
    defer wg.Done() 
    for i := range input { 
     member, err := soundcloud.GetUser(uint64(i)) 
     if err != nil{ 
      fmt.Println(err) 
     } 
     if member != nil { 
      output <- fmt.Sprint(member.Username) 
     } 
    } 
}  


func main() {  
    var err error 
    if err = soundcloud.PasswordCredentialsToken("email", "password"); err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    go func() {  
     for i := 1; i < 1000; i++ { 
       input <- i 
     } 
     close(input) 
     wg.Wait() 
     close(output) 
    }() 

    for i := 0; i < 200; i++ { 
     wg.Add(1) 
     go worker() 
    }  
    printOutput() 
} 
+0

上記のコードで 'soundcloud'とは何ですか?パッケージの場合、インポートパスは何ですか?変数の場合は、定義とそれを変更するコードを表示します。 –

+0

こんにちはKarrot、それはカスタム構造体です。私はここに参照をつけています。 https://github.com/njasm/gosoundcloud/blob/master/soundcloud.go NewSoundcloudApi – Juanvulcano

+0

[競合検出器](https://golang.org/doc/articles/race_detector.html)でコードを実行してください。問題につながる[これらの行](https://github.com/njasm/gosoundcloud/blob/0c4ec422f41aefe7d39cfefd7261733ea9423e18/soundcloud.go#L217-L221)のレースがあります。 –

答えて

1

func processAndUnmarshalResponses(resp *http.Response, err error, holder interface{}) error { 
    defer resp.Body.Close() 
    if err != nil { 
     return err 
    } 

エラーをチェックする前に、あなたはresp.Body.Close()をdeferingています。エラーがある場合、respはnilになり、逆参照するとパニックになります。必ず最初にエラーチェックを入れてください。

関連する問題