Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time: create ticker with instant first tick #17601

Closed
stevenroose opened this issue Oct 26, 2016 · 13 comments

Comments

Projects
None yet
@stevenroose
Copy link

commented Oct 26, 2016

The current time.NewTicker(time.Duration) makes its first tick after the given duration. ue to the nature of most ticker-dependent implementations, it is hard to elegantly add a tick right after calling the method.

Therefore, I want to propose a new method time.NewTickerStart(time.Duration), f.e. that does exactly the same as time.NewTicker, but fires the first tick directly after creation.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Oct 26, 2016

I note that you can write this yourself easily enough.

func NewTickerStart(d time.Duration) *time.Ticker {
    t := time.NewTicker(d)
    t.C <- time.Now()
    return t
}

I agree that this can be useful. I wonder if there is a way to find out how often people would want it. I couldn't find any cases in the standard library.

@dominikh

This comment has been minimized.

Copy link
Member

commented Oct 26, 2016

@ianlancetaylor t.C is a <-chan Time, you cannot send on that.

@stevenroose

This comment has been minimized.

Copy link
Author

commented Oct 26, 2016

@ianlancetaylor @dominikh Yeah, I noticed that. So you would have to copy the section of code underneath the first <-t.C, which is not really elegant.

@quentinmit quentinmit added this to the Go1.9Maybe milestone Nov 4, 2016

@rsc

This comment has been minimized.

Copy link
Contributor

commented Jun 12, 2017

This doesn't seem to rise to the level of new API. You don't have to "copy the section of code underneath the first <-t.C", you just have to put the code in its own function and call that function once at the start and once after each timeout interval. That seems clear enough.

@rsc rsc closed this Jun 12, 2017

@sheerun

This comment has been minimized.

Copy link

commented Jun 21, 2017

this isn't as convenient as having ticker modified because often there's extra logic surrounding handling ticket event (e.g. other cases in select {}). in this case just calling function that ticker should issue requires even more duplication

you don't need new api, just allow to send events to ticker channel

@rsc

This comment has been minimized.

Copy link
Contributor

commented Jun 21, 2017

The ticker has a field:

    C <-chan Time // The channel on which the ticks are delivered.

We can't "just allow to send events to ticker channel". That can't be changed now. (And it's debatable whether we'd do it anyway, but we can't.)

@frasca

This comment has been minimized.

Copy link

commented Jun 29, 2017

Try:

ticker := time.NewTicker(period)
for ; true; <-ticker.C {
	...
}
@matteomiraz

This comment has been minimized.

Copy link

commented Jul 31, 2017

How about select statements? Oftentimes I have to wait until some condition holds, or a context expires... and I'd like to avoid waiting for the first tick to happen.

for {
	select {
	case <-t.C:
		fmt.Println("Do work")
	case <-ctx.Done():
		fmt.Println("Done")
		return
	}
}

https://play.golang.org/p/-bXig8w-SN

@pschultz

This comment has been minimized.

Copy link

commented Jul 31, 2017

@matteomiraz, as rsc suggested earlier:

f := func() {
	fmt.Println("Do work")
}

f()
for {
	select {
	case <-t.C:
		f()
	case <-ctx.Done():
			fmt.Println("Done")
		return
	}
}
@matteomiraz

This comment has been minimized.

Copy link

commented Jul 31, 2017

That won't check if the context is valid before running the function. The correct solution is something like:

select {
case <-ctx.Done():
	return
default:
	doWork()
}
for {
	select {
	case <-t.C:
		doWork()
	case <-ctx.Done():
		return
	}
}

https://play.golang.org/p/Xl3UGqV0X5

seems quite elaborate for such a a simple use case, no?

@pschultz

This comment has been minimized.

Copy link

commented Aug 1, 2017

If the timer ticks immediately and ctx is already canceled, there is no guarantee that the t.C case will not run (the select is pseudo-random). If that's what you want you need the extra select anyway.

@rishiloyola

This comment has been minimized.

Copy link

commented Aug 27, 2017

I facing the same problem for the first tick. I would suggest Golang developer to provide this feature.

@davecheney

This comment has been minimized.

Copy link
Contributor

commented Aug 27, 2017

@rishiloyola this issue was closed on the 13th of June. Please do not comment on closed issues. I am locking this conversation to prevent further comment here. If you want to continue the discussion please consider opening a new issue, or see https://golang.org/wiki/Questions for good places to discuss Go. Thanks.

@golang golang locked and limited conversation to collaborators Aug 27, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.