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
Closed

time: create ticker with instant first tick #17601

stevenroose opened this issue Oct 26, 2016 · 13 comments
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@stevenroose
Copy link

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
Copy link
Contributor

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
Copy link
Member

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

@stevenroose
Copy link
Author

@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 the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Nov 4, 2016
@quentinmit quentinmit added this to the Go1.9Maybe milestone Nov 4, 2016
@rsc
Copy link
Contributor

rsc 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 as completed Jun 12, 2017
@sheerun
Copy link

sheerun 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
Copy link
Contributor

rsc 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
Copy link

frasca commented Jun 29, 2017

Try:

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

@matteomiraz
Copy link

matteomiraz 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
Copy link

@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
Copy link

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
Copy link

pschultz 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
Copy link

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

@davecheney
Copy link
Contributor

@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.
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests