2017-12-02 1 views
1

매우 긴 ETL 작업을 수행하는 코드가 있습니다. 가끔 네트워크 문제가 있습니다. read tcp 10.10.10.10:32423 -> 20.20.20.20:2344: i/o timeout 오류를 catch하고 작업을 다시 시도하고 싶습니다.오류가 발생한 경우 코드 반복

for { 
    err := mssql.Db.ProcessAllData(true, &processedAsutpIds, filename) 
    if err == nil { 
     fmt.Println("done.") 
     os.Exit(0) 
    } else { 
     fmt.Println(err.Error()) 
     fmt.Println("!!!! Error occurred - sleep for 5 minutes") 
     time.Sleep(time.Minute * 5) 
    } 
} 

더 관용적 인 방법으로 그것을 다시 할 수 있습니다 : 여기

내 코드?

+0

은 https : //play.golang합니다. org/p/ZQgQfmO-tK – mkopriva

+0

@mkopriva는 코드가 첫 번째 오류 – demas

+0

과 함께 올바르게 작동하는 것처럼 보입니다. 오타를 바로 잡기 전에 내 의견을 파악 했어야합니다 ('if'를'for'로 변경했습니다). 다음은 실행 가능한 예제입니다. https://play.golang.org/p/iFEsfOuvow. 기본적으로 Go의 while 루프입니다. 'for err! = nil {...'='while error do'. – mkopriva

답변

1

당신은 알렉산드르 부르 의해 "My favorite #golang retry function"에 설명 된 것과 같은 재시도 기능을 고려해 볼 수 있습니다 : 재시도 기능의 존재와

var signedContent []byte 
    err := retry(5, 2*time.Second, func() (err error) { 
     signedContent, err = signFile(unsignedFile, contents) 
     return 
    }) 
    if err != nil { 
     log.Println(err) 
     http.Error(w, err.Error(), 500) 
     return 
    } 

을 :

func retry(attempts int, sleep time.Duration, f func() error) (err error) { 
    for i := 0; ; i++ { 
     err = f() 
     if err == nil { 
      return 
     } 

     if i >= (attempts - 1) { 
      break 
     } 

     time.Sleep(sleep) 

     log.Println("retrying after error:", err) 
    } 
    return fmt.Errorf("after %d attempts, last error: %s", attempts, err) 
} 
1

내가 볼 수있는 유일한 개선은 : 그것은 암시 이후의 '다른'를 제거 :됩니다

for { 
    err := mssql.Db.ProcessAllData(true, &processedAsutpIds, filename) 
    if err == nil { 
     fmt.Println("done.") 
     os.Exit(0) 
    } 
    fmt.Println(err.Error()) 
    fmt.Println("!!!! Error occurred - sleep for 5 minutes") 
    time.Sleep(time.Minute * 5) 
} 

. go vet도 마찬가지입니다. 들여 쓰기를 수정하려면 gofmt을 사용해야합니다.

또한 특정 오류를 확인하고 네트워크 오류에 대해서만 계속 할 수 있습니다. 그러나 그것은 신청 결정입니다.

관련 문제