[erlang-questions] microseconds since midnight
Henning Diedrich
hd2010@REDACTED
Sun Jan 10 16:27:52 CET 2010
Hi Ulf,
thanks a lot for clarifying! I understood now, I think I'd disagree now
on other grounds:
now() can't fall behind over midnight due to its internal format of Mega
seconds. But it could happen to be behind universaltime() if there was a
system time change.
But I am fine for what I wanted. I also changed the code as you
suggested, as shown below. So for completeness, here are my thoughts,
skip'em they might not be worth your time:
The intent was to have a reference tick for relative comparison. As the
basis for approximation in an Internet scenario, with the clients having
10-100ms latencies, so there can never be full synchronization but an
understanding of the relative lag any package might have compared to the
fastest package ever received before.
This will allow for time based corrections of information that are worth
the effort even where they only yield something exact to some
milliseconds. In occasional moments of congestion they will easily
correct for >100ms and to catch these spikes was the main concern.
For this, the absolute offset itself is canceled out in the end and it's
only important to have it constant. Which is why Jayson has a point that
I might as well simply let the bytes roll over! But there was an
agreement on a midnight protocol, so I am going for that for this iteration.
universaltime() and now() not being in sync could pose a 'thread' to the
intended four byte format as that could result in negative or too high
offsets. So this should be the safe implementation, like you suggested:
nightsynctime_offset() ->
{MegaSec, Seconds, _} = Now = now(),
{_, Time} = calendar:now_to_datetime(Now),
SecSinceMidnight = calendar:time_to_seconds(Time),
% MidNightOffset =
(MegaSec * 1000000) + Seconds - SecSinceMidnight.
But not because now() could be called after midnight, and universaltime
before (making for a 24h gap). Because now() is not affected by midnight
with it's megasecond format. But the nature of now that you pointed to
may entail much more frequent and longer lasting cases where now() may
be trailing universaltime so that to the contrary universaltime may be
past midnight already and now still before, skewing the offset for 24h
in the other direction?
Thank you for pointing out the better implementation. No matter how
unlikely the cases might be, now it's right.
Your notes helped a lot getting a better understanding of the nature of
now() and the other time functions.
Thanks!
Henning
Ulf Wiger wrote:
> Henning Diedrich wrote:
>> Hi Ulf,
>>
>> As it is now, I don't poll time twice. But I depend on state,using a
>> constant MidNightOffset.
>
> But you do check it twice:
>
>> nightsynctime_offset() ->
>>
>> {_, Time_1} = erlang:universaltime(), %% <- HERE
>> SSMN_1 = calendar:time_to_seconds(Time_1),
>> {MegaSec_2, Seconds_2, _} = now(), %% <- AND HERE
>> % MidNightOffset =
>> (MegaSec_2 * 1000000) + Seconds_2 - SSMN_1.
>
> Rather than first calling universaltime() and then calling now,
> call now() once, and then use calendar:now_to_datetime(Now) to
> derive the other representation from that one sample.
>
> When you run small-scale tests without load, you won't notice a
> difference, but on a heavily loaded system, the admittedly unlikely
> event that the process is scheduled out between the call to
> universaltime() and the call to now() right around midnight, could
> well give you a situation where the universaltime() call shows
> {23,59,59}, while the now() call shows a time right after midnight.
>
> But as you also talked about sending these values to other nodes,
> you will of course also have to contend with the fact that the
> system clocks on different nodes can at best be sychronized to
> within a few ms using NTP. You should never rely on wall-clock
> time for synchronization across the network.
>
> But perhaps I misunderstood your intent?
>
> BR,
> Ulf W
More information about the erlang-questions
mailing list