runtimejs / runtime

[not maintained] Lightweight JavaScript library operating system for the cloud
http://runtimejs.org
Apache License 2.0
1.93k stars 127 forks source link

Time: CMOS + NTP #77

Closed facekapow closed 8 years ago

facekapow commented 9 years ago

C++ sets CMOS as the base time, and then JS synchronizes the base time with NTP time. Probably has 2 or 3 issues (one is that the CMOS time is sometimes in the future).

iefserge commented 9 years ago

This looks great, nice to have a real time support in runtime!

Few issues I found:

facekapow commented 9 years ago

1: Sure. 2: Yes, a plain uint64_t would work. 3: V8 has terrible 64-bit number support (from what i've read), so a string seems like a good way of transporting it from JS to CPP. 4: Debugging at first, now it's useless, so i'll just void it. 5: For some reason that wasn't giving me the right time, i'll try again but i'm not so sure it'll work. 6: Ok. 7: I'll fix it.

piranna commented 9 years ago

3: V8 has terrible 64-bit number support (from what i've read), so a string seems like a good way of transporting it from JS to CPP.

If you talk about the 64 bits ints support, it's inherent to the language. By design, internally the Number type is a 64 bits double, so the "safe integer limit" is at 53 bits, from there the granularity between integers increase.

facekapow commented 9 years ago

Well, either way, 64-bit integers lose precision, so a string (which can be 512MB on plain V8 or 1.9GB on Node, I believe? I don't think the number will be that long) is the best way to safely send it across JS and into C++.

facekapow commented 9 years ago

Plus, there's a Uint32 class, but no Uint64 class, no way to read the 64-bit integer from the function's arguments (unless there is a way).

iefserge commented 9 years ago

We can use a js number, a double which can store a 53 bit integer. date.getTime() will not be able to handle a 64 bit int either. Btw, we can multiply date.getTime() result by 1000 in c++.

facekapow commented 9 years ago

I feel really stupid right now, i'd forgotten about date.getTime()! Yeah, i'll use a Number.

facekapow commented 9 years ago

OK, the C++-to-JS setTime function uses a Number argument now, CMOS time is more accurate and no long in the future any more, I moved the time variable + functions to platform.h, everything is initialized in the constructor, and I made the C++-only SetTime function void.

facekapow commented 9 years ago

Should I take down this PR? Because no one has said anything since my last change to it (it's been 3 days), so... (it's just that this is on the roadmap, so I figured it'd be good to have it done), sorry if this isn't something I should comment about.

iefserge commented 9 years ago

Sorry, I've seen the PR and it looks good, but I haven't had time to integrate it into runtime. There are a few issues in TCP stack, it relies on Date.now() being monotonic and needs to be fixed first. Few minor issues with this PR (I can take care of it for you):

Great work anyway, I'll merge as soon as I can!

iefserge commented 9 years ago

@ArielAbreu Btw, we can chat in gitter or irc if you'd like :)

facekapow commented 9 years ago

I changed the buffer in order to use the U8 directly, and I use the USEARG(0); ... As<v8::Number> ... method instead of ->NumberValue(). I'm not sure what there is to initialize, though. CMOSTime doesn't even have (or need) a constructor, and Platform doesn't accept any parameters for it's constructor.

iefserge commented 9 years ago

@ArielAbreu there are uninitialized private fields

facekapow commented 9 years ago

I added a constructor that initializes CMOSTime's private variables, removes last_century (it's unused) and makes the private year variable a regular int in order to avoid a compile-time warning.

iefserge commented 9 years ago

CMOSTime* time_; allocation leaks memory, probably can change it to CMOSTime time_. Very minor issue, but let's rename set_time.js to set-time.js to be consistent.

facekapow commented 9 years ago

Fixed all this.

iefserge commented 9 years ago

@ArielAbreu going to do some tests on real hardware

kesla commented 9 years ago

Very excited about this!

facekapow commented 9 years ago

Only problem I noticed is that CMOS time returns July 18 as the day, might be an issue.

iefserge commented 9 years ago

Yep, same issue

Sat Jul 18 2015 22:34:36 GMT+0000 (GMT)
Sat Jul 18 2015 22:34:37 GMT+0000 (GMT)
Tue Jul 21 2015 22:16:53 GMT+0000 (GMT)
Tue Jul 21 2015 22:16:54 GMT+0000 (GMT)
Tue Jul 21 2015 22:16:55 GMT+0000 (GMT)
Tue Jul 21 2015 22:16:56 GMT+0000 (GMT)
``
iefserge commented 9 years ago

Looks like CMOS logic works fine on hardware, we need to fix the date though.

iefserge commented 9 years ago

One note, is that sometimes 1000ms timeout is not enough for NTP, it should probably try to send the request a few times with a couple of seconds interval each time. Or maybe we can even turn it into daemon(or background service) that's responsible for timekeeping (that's probably an idea for a separate feature).

facekapow commented 9 years ago

Theads = daemons, just sayin'... Tomorrow i'll work out the issues with CMOS.

iefserge commented 8 years ago

The beauty of non-blocking code is that there is no need to use threads:)

facekapow commented 8 years ago

Moved CMOS into JavaScript, plus I fixed it (finally).

iefserge commented 8 years ago

@ArielAbreu great work, thanks! CMOS works nicely, I fixed rounding because time was a bit off sometimes (and c++ version operates on ints) https://github.com/runtimejs/runtime/tree/real-time can you confirm this works for you?

facekapow commented 8 years ago

Yeah, it works!