본문 바로가기

Lang

[Go Lang]1분 후 정각에 로직 수행

Kafka 성능 테스트를 위해 여러 장비에서 같은 시각에 메시지 produce 할 일이 생겼다.

각 장비에서 최대한 같은 시각에 메시지 전송 시작하게 프로그램 실행 시점 1분 후 정각에 전송 시작하도록 go의 timer 를 이용해 구현해 본 부분.

	hostName, _ := os.Hostname()
	t := time.Now()
	fmt.Println("Curr :", t)
	rounded := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), 0, 0, t.Location())
	fmt.Println("Round :", rounded)
	after1m := rounded.Local().Add(time.Minute * time.Duration(1))
	fmt.Println("After 1M :", after1m)
	diff := after1m.Sub(t).Milliseconds()
	timer := time.NewTimer(time.Millisecond * time.Duration(diff))
	<-timer.C
	fmt.Println(hostName, ":", time.Now())

출력 결과는 다음과 같다.

Curr : 2020-01-22 14:51:27.4983399 +0900 KST m=+0.015999001
Round : 2020-01-22 14:51:00 +0900
KST After 1M : 2020-01-22 14:52:00 +0900 KST
Client1 : 2020-01-22 14:52:00.1717963 +0900 KST m=+32.690040301

현재 시각을 Round 한 후 여기에 1분 더해 1분 후 정각을 구하고 이 시각과 현재 시간의 Milliseconds 값을 구해서 timer 로 그 duration 후에 로직 실행하도록 했다. 내부 처리 시간(특히, timer) 때문에 약간의 오차가 있긴 하지만 그런대로 의도한 결과 구할 수 있었다.

timer 이용할 때 주의할 점은 인자 타입이 duration 이란거.

time.NewTimer(time.Millisecond * diff)  이런 식으로 int(64) 값 그대로 전달하면 에러 남.

5초 후 실행을 위해서 살짝 수정한 예.

t := time.Now()
rounded := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), 0, t.Location())
after := rounded.Local().Add(time.Second * time.Duration(5))
diff := after.Sub(t).Milliseconds()
timer := time.NewTimer(time.Millisecond * time.Duration(diff))
<-timer.C
fmt.Println("exec time :", time.Now())