我不确定为什么媒体普遍说 Google 的 TrueTime API 难以复制(Wired、Slashdot 等)。
我可以理解要获得谷歌正在实现的低错误间隔是一件多么困难的事情,但我不明白 API 本身有多困难。
例如,我制作了一个 hacked together 版本。这是间隔。
typedef struct TT_interval {
struct timeval earliest;
struct timeval latest;
} TT_interval;
这是现在的功能。
int TT_now(TT_interval* interval)
{
struct ntptimeval tv;
struct timeval delta;
struct timeval* earliest_p = &(interval->earliest);
struct timeval* latest_p = &(interval->latest);
struct timeval* now_p = &(tv.time);
struct timeval* delta_p = δ
timerclear(&delta);
timerclear(&interval->earliest);
timerclear(&interval->latest);
if(ntp_gettime(&tv) == 0) {
tv.maxerror = tv.maxerror > 0 ? tv.maxerror : -(tv.maxerror);
delta.tv_sec = delta.tv_sec + (tv.maxerror / 1000);
delta.tv_usec = delta.tv_usec + ((tv.maxerror % 1000) * 1000);
if(delta.tv_usec > 1000000) {
delta.tv_usec -= 1000000;
delta.tv_sec++;
}
timeradd(now_p, delta_p, latest_p);
timersub(now_p, delta_p, earliest_p);
} else {
printf("error on ntp_gettime. %s\n", strerror(errno));
return ERROR;
}
return SUCCESS;
}
最后,这里是 before 和 after 函数(它们是 now 函数的包装器,可以使用一些 DRY 重构)。
int TT_before(TT_interval* interval, bool* success)
{
struct timeval* latest_p;
struct timeval* earliest_p;
TT_interval now;
if(TT_now(&now) != SUCCESS) {
return ERROR;
}
latest_p = &(interval->latest);
earliest_p = &(now.earliest);
if(timercmp(latest_p, earliest_p, <) != 0) {
*success = true;
return SUCCESS;
} else {
*success = false;
return SUCCESS;
}
return ERROR;
}
int TT_after(TT_interval* interval, bool* success)
{
struct timeval* latest_p;
struct timeval* earliest_p;
TT_interval now;
if(TT_now(&now) != SUCCESS) {
return ERROR;
}
earliest_p = &(interval->latest);
latest_p = &(now.earliest);
if(timercmp(latest_p, earliest_p, <) != 0) {
*success = true;
return SUCCESS;
} else {
*success = false;
return SUCCESS;
}
return ERROR;
}
我似乎得到了大约 5,000us 到 350,000us 的间隔错误(使用公共 NTPd)。这与谷歌的数字相去甚远,但你需要从某个地方开始。
除了性能不佳之外,这种设计是否存在重大缺陷会阻止像 Spanner 这样的东西被构建在上面?