]> arthur.barton.de Git - netdata.git/commitdiff
prevent the charts from moving into the future
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Tue, 21 Feb 2017 20:26:56 +0000 (22:26 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Tue, 21 Feb 2017 23:00:28 +0000 (01:00 +0200)
src/clocks.c
src/clocks.h
src/rrdpush.c
src/rrdset.c

index 88d3783e8e6c6233ea26ce17617b76a352890014..239b36e525a1ef894474681dea857146eb30443b 100644 (file)
@@ -74,6 +74,14 @@ inline usec_t timeval_usec(struct timeval *tv) {
     return (usec_t)tv->tv_sec * USEC_PER_SEC + tv->tv_usec;
 }
 
+inline susec_t dt_usec_signed(struct timeval *now, struct timeval *old) {
+    usec_t ts1 = timeval_usec(now);
+    usec_t ts2 = timeval_usec(old);
+
+    if(likely(ts1 >= ts2)) return (susec_t)(ts1 - ts2);
+    return -((susec_t)(ts2 - ts1));
+}
+
 inline usec_t dt_usec(struct timeval *now, struct timeval *old) {
     usec_t ts1 = timeval_usec(now);
     usec_t ts2 = timeval_usec(old);
index 895f09ab4dbeac2b7caba20fed887a9df6b69b88..c410a0521661e329a0751789379bf1487534a79d 100644 (file)
@@ -13,6 +13,7 @@ typedef int clockid_t;
 #endif
 
 typedef unsigned long long usec_t;
+typedef long long susec_t;
 
 typedef usec_t heartbeat_t;
 
@@ -94,6 +95,7 @@ extern usec_t now_boottime_usec(void);
 
 extern usec_t timeval_usec(struct timeval *ts);
 extern usec_t dt_usec(struct timeval *now, struct timeval *old);
+extern susec_t dt_usec_signed(struct timeval *now, struct timeval *old);
 
 extern void heartbeat_init(heartbeat_t *hb);
 
index de2a455763287ed736ee12f206580be19878a887..bc1c027bad2a7160cc269596cce48766e68a5bfa 100644 (file)
@@ -60,7 +60,7 @@ static inline void send_chart_definition(RRDSET *st) {
 }
 
 static inline void send_chart_metrics(RRDSET *st) {
-    buffer_sprintf(rrdpush_buffer, "BEGIN %s %llu\n", st->id, st->usec_since_last_update);
+    buffer_sprintf(rrdpush_buffer, "BEGIN %s %llu\n", st->id, (st->counter_done > 60)?st->usec_since_last_update:0);
 
     RRDDIM *rd;
     rrddim_foreach_read(rd, st) {
@@ -83,6 +83,11 @@ static void reset_all_charts(void) {
 
         RRDSET *st;
         rrdset_foreach_read(st, host) {
+
+            // make it re-align the current time
+            // on the remote host
+            st->counter_done = 0;
+
             rrdset_rdlock(st);
 
             RRDDIM *rd;
index 3432788b941c80200c18f69f9d03eb17e71a0dfb..da84186f6ce9fc3622cc87b41cff427e5d91e070 100644 (file)
@@ -529,26 +529,40 @@ inline void rrdset_next_usec(RRDSET *st, usec_t microseconds) {
 //        usec_t now_usec = timeval_usec(&now);
 //        usec_t last_usec = timeval_usec(&st->last_collected_time);
 //#endif
-        usec_t since_last_usec = dt_usec(&now, &st->last_collected_time);
+        susec_t since_last_usec = dt_usec_signed(&now, &st->last_collected_time);
+
+        if(unlikely(since_last_usec < 0)) {
+            // oops! the database is in the future
+            error("Database for chart '%s' on host '%s' is %lld microseconds in the future.", st->id, st->rrdhost->hostname, -since_last_usec);
+            memcpy(&st->last_collected_time, &now, sizeof(struct timeval));
+            st->last_collected_time.tv_sec -= st->update_every;
+
+            memcpy(&st->last_updated, &now, sizeof(struct timeval));
+            timeval_align(&st->last_updated, st->update_every);
+            st->last_updated.tv_sec -= st->update_every;
+
+            microseconds = st->update_every * USEC_PER_SEC;
+            since_last_usec = st->update_every * USEC_PER_SEC;
+        }
 
         // verify the microseconds given is good
-        if(unlikely(microseconds > since_last_usec)) {
-            debug(D_RRD_CALLS, "dt %llu usec given is too big - it leads %llu usec to the future, for chart '%s' (%s).", microseconds, microseconds - since_last_usec, st->name, st->id);
+        if(unlikely(microseconds > (usec_t)since_last_usec)) {
+            debug(D_RRD_CALLS, "dt %llu usec given is too big - it leads %llu usec to the future, for chart '%s' (%s).", microseconds, microseconds - (usec_t)since_last_usec, st->name, st->id);
 
 //#ifdef NETDATA_INTERNAL_CHECKS
 //            if(unlikely(last_usec + microseconds > now_usec + 1000))
-//                error("dt %llu usec given is too big - it leads %llu usec to the future, for chart '%s' (%s).", microseconds, microseconds - since_last_usec, st->name, st->id);
+//                error("dt %llu usec given is too big - it leads %llu usec to the future, for chart '%s' (%s).", microseconds, microseconds - (usec_t)since_last_usec, st->name, st->id);
 //#endif
 
-            microseconds = since_last_usec;
+            microseconds = (usec_t)since_last_usec;
         }
-        else if(unlikely(microseconds < since_last_usec * 0.8)) {
-            debug(D_RRD_CALLS, "dt %llu usec given is too small - expected %llu usec up to -20%%, for chart '%s' (%s).", microseconds, since_last_usec, st->name, st->id);
+        else if(unlikely(microseconds < (usec_t)since_last_usec * 0.8)) {
+            debug(D_RRD_CALLS, "dt %llu usec given is too small - expected %llu usec up to -20%%, for chart '%s' (%s).", microseconds, (usec_t)since_last_usec, st->name, st->id);
 
 //#ifdef NETDATA_INTERNAL_CHECKS
-//            error("dt %llu usec given is too small - expected %llu usec up to -20%%, for chart '%s' (%s).", microseconds, since_last_usec, st->name, st->id);
+//            error("dt %llu usec given is too small - expected %llu usec up to -20%%, for chart '%s' (%s).", microseconds, (usec_t)since_last_usec, st->name, st->id);
 //#endif
-            microseconds = since_last_usec;
+            microseconds = (usec_t)since_last_usec;
         }
     }
     debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
@@ -596,6 +610,9 @@ static inline void rrdset_done_push_int(RRDSET *st) {
     }
 
     rrdset_done_push(st);
+
+    st->counter++;
+    st->counter_done++;
 }
 
 void rrdset_done(RRDSET *st) {