Skip to content

RussellLuo/goodtimer

Repository files navigation

goodtimer

Golang timer for humans.

goodtimer is a thin wrapper around the standard time.Timer, and it tries to play two roles:

  1. A library that helps you use time.Timer more easily.
  2. As well as a demonstration that shows you how to use time.Timer correctly.

中文博客:使用 Golang Timer 的正确方式

Installation

$ go get -u github.com/RussellLuo/goodtimer

Documentation

For usage and examples see the Godoc.

Why?!

TL;DR: The timer created with time.NewTimer is hard to use correctly.

Timer.Stop

Per the documentation of Timer.Stop, to stop the timer created with time.NewTimer, you need to check the return value and drain the channel if necessary:

if !t.Stop() {
	<-t.C
}

But the draining operation will be blocked if the the program has already received from the Timer's channel before. So someone suggests doing a non-blocking draining:

if !t.Stop() {
	select {
	case <-t.C: // try to drain the channel
	default:
	}
}

However, there is a race condition between draining the channel and sending time into the channel, which may lead to a undrained channel.

Timer.Reset

To reset a timer, is must have expired or be stopped before. So Timer.Reset has almost the same issue with Timer.Stop.

Solutions

Finally, as Russ Cox suggested (here and here), the correct way to use time.Timer is:

  • All the Timer operations (Timer.Stop, Timer.Reset and receiving from or draining the channel) should be done in the same goroutine.
  • The program should manage an extra status showing whether it has received from the Timer's channel or not.

Releases

No releases published

Packages

No packages published

Languages