jonboulle / clockwork

a fake clock for golang
Apache License 2.0
625 stars 57 forks source link

Refactor to avoid channels and goroutines #44

Closed gagern closed 1 year ago

gagern commented 2 years ago

In terms of features, the addition of AfterFunc is the main benefit here. Otherwise it addresses a number of bugs, mainly around out-of-order or duplicate delivery of events, as exposed by the various tests added by these changes.

These changes merge the sleeper and the fakeTimer task. Now a fakeTimer object is used to represent any future event on the timeline of a given fake clock. When the time advances to that point, a callback on the fakeTimer gets called. This makes sending to a channel only one of many possible responses on expiry. Not using channels, but instead an internal callback that gets called with the clock's lock held, allows using the timer far more flexible. It is now also the basis of ticker and of the After method. This change in general will do more things while holding the clock's lock, leading to more consistent behavior and less risk of data races.

Basing After on Timer instead of the other way round also allows clearing the future events when timers get stopped or reset. This in turn helps BlockUntil actually track active blockers, ignoring obsolete ones that used to exist in the past.

This fixes https://github.com/jonboulle/clockwork/issues/42.

muir commented 1 year ago

Oh! I see this has AfterFunc too. Can this get merged? Then #45 can be closed w/o merging.

rubensayshi commented 1 year ago

@sagikazarmark could you tag a new release with these changes?

the old code (v0.3.0) leavings zombie go routines if .Stop() wasn't called on a timer

sagikazarmark commented 1 year ago

Unfortunately this change seems to introduce some regressions. Waiting for those to be fixed.