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
Milestone

Comments

@stevenroose
Copy link

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

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

@dominikh dominikh commented Oct 26, 2016

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

@stevenroose
Copy link
Author

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

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

@sheerun 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 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 frasca commented Jun 29, 2017

Try:

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

@matteomiraz 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

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

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

@pschultz 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

@rishiloyola rishiloyola commented Aug 27, 2017

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

@davecheney
Copy link
Contributor

@davecheney davecheney 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.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.