--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Based on some of the conversations here on the mailing list, on IRC, and with some coworkers I've been musing about taking a shot at designing an os/clock package.
I don't have any serious designs put together, but I think it would at a minimum be good to provide e.g. clock.System(), .Monotonic(), and .HighPrecision(). They woul d construct Clock objects (or something of that nature). I don't think there would be any way to interact with or extract a time.Time for any of these, though I would expect that the "time" package would have a FromTicks(clock.Ticks) time.Duration or something similar. I would just try my hand at this as a third party package, but I think that there are strong arguments for being able to tell the "time" package that you want to use a new Clock for e.g. Sleep, After, etc (probably in a similar way that you can create your own rand.Source or log.Logger). It's also possible that we want to use the monotonic clock when we're computing timeouts and such.
I definitely wouldn't try to get this into go 1.2, and it would probably require taking some time to soak before going out in a 1.3 or 1.4.
A few thoughts:
- It would make sense to develop as a non-standard-library package like dev/os/clock, because some work on the API will be required. It will be difficult to get it right at the first cut.
- The clock type should be an interface (clock.Interface?), which would allow users to invent their own clocks.
- A standard clock would then simply clock.Monotonic as implementation of the clock interface.
- The only reason to introduce a Ticks type would be to support higher than nanosecond resolution. But this would then clearly depend on the clock. I suggest to stay with time.Duration and nanosecond support, which is what clock_gettime() supports.
- While the clock package could implement their own Timer and Ticker types, it would look nicer if the time types would be extended to support clock.Interface. (One wonders whether they should have been interfaces from the very beginning at least I would make them interfaces in the clock package.)
The last point would be an argument to extend the time package to support clocks.
On Thursday, August 22, 2013 4:53:34 AM UTC+2, Kyle Lemons wrote:Based on some of the conversations here on the mailing list, on IRC, and with some coworkers I've been musing about taking a shot at designing an os/clock package.I don't have any serious designs put together, but I think it would at a minimum be good to provide e.g. clock.System(), .Monotonic(), and .HighPrecision(). They woul d construct Clock objects (or something of that nature). I don't think there would be any way to interact with or extract a time.Time for any of these, though I would expect that the "time" package would have a FromTicks(clock.Ticks) time.Duration or something similar. I would just try my hand at this as a third party package, but I think that there are strong arguments for being able to tell the "time" package that you want to use a new Clock for e.g. Sleep, After, etc (probably in a similar way that you can create your own rand.Source or log.Logger). It's also possible that we want to use the monotonic clock when we're computing timeouts and such.
I definitely wouldn't try to get this into go 1.2, and it would probably require taking some time to soak before going out in a 1.3 or 1.4.My motivation for this is the fact that time is difficult, and I think it's something that if done correctly in a standard package, there is actually a reasonable chance that (in a similar way that the "time" package makes it easier to keep Times and Durations separate) it could make it easier to do correctly across the board. I also think that it might be interesting to swap out the clock with a fake clock so that you could make instant tests that nevertheless think time is passing in a similar way that is done on the playground. One potentially huge benefit could be basing a time.Ticker or a time.After off of the HPET -- the hardware has the ability to fire very precisely timed interrupts both periodically and as a one-shot.After having gone back and forth for awhile, I think the most straightforward way to do it is to interact with the TSC, HPET, etc directly, though I'm likely to change my mind again tomorrow and think using the OS mechanisms is easier. The system clock probably should just use the os mechanism. Different operating systems provide varying support for especially HPET, but I believe that Windows after XP SP3, linux 2.6+, and mac os 10+ all provide all of the facilities we'd need (and most also providing access to 64-bit HPET if available).I'm wondering whether this is something that would be worth drawing up more formally as a design for further thought or whether it is something that would be best left as a third party package or not at all.Comments welcome.
--
I agree that monotonic sleeps seem like a reasonable default, but I don't think we can do that without potentially breaking attempting to sleep until a particular date+time, because you could (possibly wildly) overshoot in the presence of clock steps.
I think that any function that accepts relative time (time.Sleep,time.Ticker) must use monotonic time. It is the most reasonable thing
to do. Do you agree?
So based on all that, I think the plan should be:
1. Convert most existing things to monotonic time (time.Sleep,
time.Ticker). This essentially fixes bugs.
2. Introduce a function to sleep till specified real time, e.g.
time.SleepUntil(time.Time), time.NewTimerUntil(time.Time).
3. Convert socket deadlines to monotonic time, and probably introduce
SetTimeout(time.Duration) and say that if you use SetDeadline you will
be skrewed up in presence of time steps.
4. Expose monotonic time to user, e.g. time.MonoNow().
On Sat, Aug 24, 2013 at 5:16 AM, Kyle Lemons <kev...@google.com> wrote:Without time steps both sleeps behave the same way, right?
> I agree that monotonic sleeps seem like a reasonable default, but I don't
> think we can do that without potentially breaking attempting to sleep until
> a particular date+time, because you could (possibly wildly) overshoot in the
> presence of clock steps.
In the presence of time steps, it's somewhat unclear to me what a user
can potentially want, and what a reasonable behavior of sleeps can be
at all.
I think that any function that accepts relative time (time.Sleep,
time.Ticker) must use monotonic time. It is the most reasonable thing
to do. Do you agree?
Net deadlines use absolute time. I think we need to convert the
deadline to relative time ASAP and then use relative sleep on
monotonic clock as well.
Here is an issue with API that we can not fix
-- if a user adds time.Minute to time.Now(), then time step happens,
then we subtract the result from time.Now(), we get garbage.
As for your sleep-till-midnight use case. This looks like a very
special case.
(1) it is not supported by current implementation in any
way, so we can not break anything existing.
(2) it must necessary
accept absolute time (because if you say sleep for 1 hour, but mean
sleep till midnight, there is no way we can figure your intention
out).
So based on all that, I think the plan should be:
1. Convert most existing things to monotonic time (time.Sleep,
time.Ticker). This essentially fixes bugs.
2. Introduce a function to sleep till specified real time, e.g.
time.SleepUntil(time.Time), time.NewTimerUntil(time.Time).
3. Convert socket deadlines to monotonic time, and probably introduce
SetTimeout(time.Duration) and say that if you use SetDeadline you will
be skrewed up in presence of time steps.
4. Expose monotonic time to user, e.g. time.MonoNow().
>> Here is an issue with API that we can not fixI meant that it is garbage in the sense that from users point of view
>> -- if a user adds time.Minute to time.Now(), then time step happens,
>> then we subtract the result from time.Now(), we get garbage.
>
>
> Really? I don't think our time arithmetic will ever give you garbage.
> http://play.golang.org/p/FEK7AA1omh We just need to define what happens
> when you try to sleep a negative amount, which should be easy: you don't
> sleep.
it's essentially random value.
Any call to SetDeadline(time.Now().Add(time.Minute)) is equivalent to
SetDeadline(randomTime()).
>> As for your sleep-till-midnight use case. This looks like a veryAh, I see.
>> special case.
>
>
> It's a specific example of a reasonably common case. If you're scheduling
> things to run (system upgrades, a software rollout, cron, email
> notifications), you'll often be doing it in terms of wall clock time, so
> that a human checking his watch will know when it's going to happen. At
> present you're unlikely to get too far off, because leap seconds are the
> only thing that should cause a time step in a steady state NTP system, but
> you may well write the code in the way I describe (sleep for
> target-time.Now() in a loop) because it is the closest analogy to what you'd
> do as a human (keep checking your watch until it's time to do your action).
Talking about differences between real and monotonic time, if real
time does not change, it not interesting. Use any, they are the same.
There are also software bugs, administrators and desktop systems with users.
Ordinary user does not understand what is UTC time and timezone. So
when he travels to -12 timezone, he changes his *time* by -12hrs. Then
he connects to internet and NTP changes his time back by +12hrs. Then
it repeats for the whole travel.
During this half of his Go programs and another half crash with timeouts.
Let's assume for this discussion that time periodically randomly
changes by +/- year.
Now what does it mean to do something every midnight?
If the same midnight happens twice, do you want to do something two times?
If from one midnight to the next passes a week of monotonic time, how
the system must behave?
... until a certain amount of time has actually passed in what time
>> (1) it is not supported by current implementation in any
>> way, so we can not break anything existing.
>
>
> Actually, in the current implementation, I believe the API allows you to
> sleep until the clock says a specified time pretty easily; what it does not
> currently provide is a way to sleep until a certain amount of time has
> actually passed.
(monotonic/real)?
I believe in presence of time changes it behaves essentially randomly now.
>> (2) it must necessaryYes, but on the other hand, the next midnight can suddenly happen next
>> accept absolute time (because if you say sleep for 1 hour, but mean
>> sleep till midnight, there is no way we can figure your intention
>> out).
>
>
> It's true the Sleep(1*time.Hour) carries no intent; however, it is easier to
> recover if Sleep(1*time.Hour) sleeps for less than an hour -- the calling
> application can always sleep again. You can't go back in time if you
> oversleep.
nanosecond.
That's why I say that I can not imagine any sane semantics for such
sleep in presence of chaotic time changes (and if they do not happen,
then all this become trivial and nothing to talk about).
>> So based on all that, I think the plan should be:It does not work now. So it's not a problem :)
>> 1. Convert most existing things to monotonic time (time.Sleep,
>> time.Ticker). This essentially fixes bugs.
>
>
> As you said above, time.Sleep carries no intent. Therefore, you can't say
> whether this will introduce or fix bugs. I have written at least one
> application that uses sleep in the way I describe. Worse, making the change
> will not visibly break anybody that was using them in that way, so they may
> not notice until it's too late.
>> 2. Introduce a function to sleep till specified real time, e.g.You can use the clock in your program, but you can't fix all the
>> time.SleepUntil(time.Time), time.NewTimerUntil(time.Time).
>
>
> I think these introductions would be a good start. Perhaps introducing them
> now and giving users until go 2 to start using them would allow you to make
> Sleep and Ticker use monotonic time without breaking anybody. Of course,
> then the suggestion would be to make SleepMono and NewMonoTimer... but now
> we have a major API addition. Thus my suggestion to introduce a Clock
> primitive, so you could call time.SetClock(clk) and make all calls to
> time.Sleep and time.NewTimer use it (or call time.New(clk).Sleep and such to
> not change out the clock used by the entire package). In this way, you can
> maintain the current behavior in perpetuity, while still allowing users who
> need one behavior or the other to specify it.
packages you use.
>> 3. Convert socket deadlines to monotonic time, and probably introduceI am not proposing new behavior (like timeout for each separate net
>> SetTimeout(time.Duration) and say that if you use SetDeadline you will
>> be skrewed up in presence of time steps.
>
>
> I'm not convinced about this part quite yet; see above.
call). SetTimeout is just a non-broken way to communicate when you
want the deadline to happen.
>> 4. Expose monotonic time to user, e.g. time.MonoNow().Well, I don't have a strong position right now about how exactly the
>
>
> With a clock primitive, you can provide these directly from the clocks:
> "os/clock".Monotonic.Now() etc. I actually don't think time.MonoNow would
> be a good API, because it would seem to correlate to Now() which returns a
> Time, and MonoNow would actually need to be a counter, e.g. uint64.
API must look like. But FWIW MonoTime() can return Time from some
unspecified point in time.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/D11F4zMs-E0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/D11F4zMs-E0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.