Discussion:
[elm-discuss] Unexpected Time.every drift over time
RGBboy
2017-06-04 17:17:44 UTC
Permalink
I have been using Time.every for a project that requires ticks at a
constant interval. I found that different platforms drift by varying
amounts. Some platforms seem to oscillate around the desired 0 millisecond
drift. This is acceptable for my use case. However some platforms
constantly increase in drift over time. This is unacceptable for my use
case.

I put together an example application with Ellie that exhibits the issue (
https://ellie-app.com/3p4mpnVyTj8a1/2). If you compile and open up the
console you can see how much the application drifts over time in your
browser. I have a bunch of results from the platforms that I have access
to. You can see that Safari and Node.js both increase in drift over time:

*Chrome 58.0.3029.110:*

DRIFT: Nothing
DRIFT: Just 4
DRIFT: Just 4
DRIFT: Just -1
DRIFT: Just 0
DRIFT: Just 1
DRIFT: Just 2
DRIFT: Just 3
DRIFT: Just 5
DRIFT: Just 1
DRIFT: Just 3
DRIFT: Just 4
DRIFT: Just -1
DRIFT: Just 1
DRIFT: Just 0
DRIFT: Just 2


*Firefox 47.0:*

DRIFT: Nothing
DRIFT: Just -2
DRIFT: Just 0
DRIFT: Just 2
DRIFT: Just -2
DRIFT: Just -3
DRIFT: Just -1
DRIFT: Just 0
DRIFT: Just -2
DRIFT: Just -3
DRIFT: Just 3
DRIFT: Just -2
DRIFT: Just -3
DRIFT: Just -2
DRIFT: Just -1
DRIFT: Just -2


*Safari 10.1:*

DRIFT: Nothing
DRIFT: Just 0
DRIFT: Just 0
DRIFT: Just 4
DRIFT: Just 3
DRIFT: Just 4
DRIFT: Just 4
DRIFT: Just 4
DRIFT: Just 5
DRIFT: Just 5
DRIFT: Just 6
DRIFT: Just 7
DRIFT: Just 8
DRIFT: Just 9
DRIFT: Just 10
DRIFT: Just 11


*Node.js 7.10.0:*

DRIFT: Nothing
DRIFT: Just 2
DRIFT: Just 5
DRIFT: Just 6
DRIFT: Just 10
DRIFT: Just 17
DRIFT: Just 22
DRIFT: Just 27
DRIFT: Just 32
DRIFT: Just 37
DRIFT: Just 40
DRIFT: Just 43
DRIFT: Just 45
DRIFT: Just 51
DRIFT: Just 54
DRIFT: Just 56


*Node.js 8.0.0:*

DRIFT: Nothing
DRIFT: Just 4
DRIFT: Just 6
DRIFT: Just 7
DRIFT: Just 8
DRIFT: Just 12
DRIFT: Just 14
DRIFT: Just 14
DRIFT: Just 14
DRIFT: Just 20
DRIFT: Just 23
DRIFT: Just 25
DRIFT: Just 25
DRIFT: Just 30
DRIFT: Just 32
DRIFT: Just 37


There are a number of ways I can mitigate the issue but I am wondering
where is the most pragmatic place for this to be fixed?

*The given platform?*

This would mean Safari, Node and any other inconsistent platforms fix this.
This seems like it is extremely unlikely to happen. For example this is a
known issue across multiple node version that was raised almost a year ago
with no fix yet (https://github.com/nodejs/node/issues/7346).

*Elm's Core Time module?*

This would give consistent behaviour for all consumers no matter what
platform they are running on. I have made a proof of concept that enables
this so it is possible. I'm just not sure if this is a change that aligns
with the intension of the module.

*My application?*

There are a number of things I could do within my application to mitigate
the issue (which I am already doing). For example I could track the drift
and counter it in my subscription. My only reservation here is that others
will face the same issue.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Aaron VonderHaar
2017-06-04 17:51:48 UTC
Permalink
Time.every relies on javascript's setInterval. Do you see the same drift
in Safari/node using setInterval?

If you need more accurate timing, it's possible to attempt that now using a
combination of Time.now and Process.sleep (every time you get a message,
check the timestamp and calculate how long you want to sleep for).
Process.sleep relies on setTimeout, so this can still drift on any given
sleep, but you'd be able to calculate a correction when you trigger the
next sleep.

Also note that it's better if possible to change your logic to not rely on
fixed-interval messages, since Javascript itself does not provide a method
of real-time scheduling. Instead it's recommended to use the Time value in
the message to determine how much you need to update. (This also would let
you swap in AnimationFrame.times if you want more responsive updates, which
is also recommended over using Time.every with a very small interval.)
Post by RGBboy
I have been using Time.every for a project that requires ticks at a
constant interval. I found that different platforms drift by varying
amounts. Some platforms seem to oscillate around the desired 0 millisecond
drift. This is acceptable for my use case. However some platforms
constantly increase in drift over time. This is unacceptable for my use
case.
I put together an example application with Ellie that exhibits the issue (
https://ellie-app.com/3p4mpnVyTj8a1/2). If you compile and open up the
console you can see how much the application drifts over time in your
browser. I have a bunch of results from the platforms that I have access
*Chrome 58.0.3029.110:*
DRIFT: Nothing
DRIFT: Just 4
DRIFT: Just 4
DRIFT: Just -1
DRIFT: Just 0
DRIFT: Just 1
DRIFT: Just 2
DRIFT: Just 3
DRIFT: Just 5
DRIFT: Just 1
DRIFT: Just 3
DRIFT: Just 4
DRIFT: Just -1
DRIFT: Just 1
DRIFT: Just 0
DRIFT: Just 2
*Firefox 47.0:*
DRIFT: Nothing
DRIFT: Just -2
DRIFT: Just 0
DRIFT: Just 2
DRIFT: Just -2
DRIFT: Just -3
DRIFT: Just -1
DRIFT: Just 0
DRIFT: Just -2
DRIFT: Just -3
DRIFT: Just 3
DRIFT: Just -2
DRIFT: Just -3
DRIFT: Just -2
DRIFT: Just -1
DRIFT: Just -2
*Safari 10.1:*
DRIFT: Nothing
DRIFT: Just 0
DRIFT: Just 0
DRIFT: Just 4
DRIFT: Just 3
DRIFT: Just 4
DRIFT: Just 4
DRIFT: Just 4
DRIFT: Just 5
DRIFT: Just 5
DRIFT: Just 6
DRIFT: Just 7
DRIFT: Just 8
DRIFT: Just 9
DRIFT: Just 10
DRIFT: Just 11
*Node.js 7.10.0:*
DRIFT: Nothing
DRIFT: Just 2
DRIFT: Just 5
DRIFT: Just 6
DRIFT: Just 10
DRIFT: Just 17
DRIFT: Just 22
DRIFT: Just 27
DRIFT: Just 32
DRIFT: Just 37
DRIFT: Just 40
DRIFT: Just 43
DRIFT: Just 45
DRIFT: Just 51
DRIFT: Just 54
DRIFT: Just 56
*Node.js 8.0.0:*
DRIFT: Nothing
DRIFT: Just 4
DRIFT: Just 6
DRIFT: Just 7
DRIFT: Just 8
DRIFT: Just 12
DRIFT: Just 14
DRIFT: Just 14
DRIFT: Just 14
DRIFT: Just 20
DRIFT: Just 23
DRIFT: Just 25
DRIFT: Just 25
DRIFT: Just 30
DRIFT: Just 32
DRIFT: Just 37
There are a number of ways I can mitigate the issue but I am wondering
where is the most pragmatic place for this to be fixed?
*The given platform?*
This would mean Safari, Node and any other inconsistent platforms fix
this. This seems like it is extremely unlikely to happen. For example this
is a known issue across multiple node version that was raised almost a year
ago with no fix yet (https://github.com/nodejs/node/issues/7346).
*Elm's Core Time module?*
This would give consistent behaviour for all consumers no matter what
platform they are running on. I have made a proof of concept that enables
this so it is possible. I'm just not sure if this is a change that aligns
with the intension of the module.
*My application?*
There are a number of things I could do within my application to mitigate
the issue (which I am already doing). For example I could track the drift
and counter it in my subscription. My only reservation here is that others
will face the same issue.
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
RGBboy
2017-06-05 07:00:41 UTC
Permalink
On Safari/node setInterval does indeed exhibit the same issue so this is
not a bug in Elms core. However Elm does have an opportunity to smooth this
inconsistency out.

What I have done so far to mitigate this issue is essentially what you
describe. I have experimented with a couple of different solutions to find
one that is simple to use. The implementation that I have found most simple
so far (for the consumer) is an effects manager that uses Time.now and
Process.sleep instead of setInterval.

As for not relying on fixed interval messages, this is not something that
my application can do. I am running a deterministic simulation on a server
and multiple clients. In order for the clients and server to stay in sync
they must stay close in timestep. It does have tolerance for some drift,
however as drift increases the servers simulation gets more out of sync
with the clients.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Zachary Kessin
2017-06-05 09:23:04 UTC
Permalink
Trying to keep a server and clients in time sync is a really hard problem!
Actually, it's more or less an impossible problem in the general case as
time drift between nodes in inevitable and timing accuracy is limited by
relativity. I would look at this article
http://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time
as well as this one http://ferd.ca/beating-the-cap-theorem-checklist.html

Zach
ᐧ
Post by RGBboy
On Safari/node setInterval does indeed exhibit the same issue so this is
not a bug in Elms core. However Elm does have an opportunity to smooth this
inconsistency out.
What I have done so far to mitigate this issue is essentially what you
describe. I have experimented with a couple of different solutions to find
one that is simple to use. The implementation that I have found most simple
so far (for the consumer) is an effects manager that uses Time.now and
Process.sleep instead of setInterval.
As for not relying on fixed interval messages, this is not something that
my application can do. I am running a deterministic simulation on a server
and multiple clients. In order for the clients and server to stay in sync
they must stay close in timestep. It does have tolerance for some drift,
however as drift increases the servers simulation gets more out of sync
with the clients.
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
Zach Kessin
Teaching Web Developers to test code to find more bugs in less time
Skype: zachkessin
+972 54 234 3956 / +44 203 734 9790 / +1 617 778 7213
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...