From a616db46e0c2196c23d5d81895c550f9f368ecc7 Mon Sep 17 00:00:00 2001
From: Luca Bruno <luca.bruno@coreos.com>
Date: Fri, 26 Jul 2019 15:10:13 +0000
Subject: [PATCH 1/3] graph-builder/cargo: add chrono

---
 graph-builder/Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/graph-builder/Cargo.toml b/graph-builder/Cargo.toml
index 771405fab..388c7e5b6 100644
--- a/graph-builder/Cargo.toml
+++ b/graph-builder/Cargo.toml
@@ -7,10 +7,10 @@ edition = "2018"
 [dependencies]
 actix = "^0.8.3"
 actix-web = "^1.0.2"
+chrono = "^0.4.7"
 cincinnati = { path = "../cincinnati" }
 commons = { path = "../commons" }
 dkregistry = { git = "https://github.com/camallo/dkregistry-rs.git", rev = "eb6349f2b99cd3dbd681d18d692a8c69e2e7b339" }
-
 env_logger = "^0.6.0"
 failure = "^0.1.1"
 flate2 = "^1.0.1"

From b02d751ff3f65439e9feaff8e4e6c38eba9dff12 Mon Sep 17 00:00:00 2001
From: Luca Bruno <luca.bruno@coreos.com>
Date: Fri, 26 Jul 2019 15:10:29 +0000
Subject: [PATCH 2/3] lockfile: refresh after cargo changes

---
 Cargo.lock | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Cargo.lock b/Cargo.lock
index 9f77aef21..d5cc9ec74 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -979,6 +979,7 @@ version = "0.1.0"
 dependencies = [
  "actix 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "actix-web 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "cincinnati 0.1.0",
  "commons 0.1.0",
  "dkregistry 0.3.0-alpha.0 (git+https://github.com/camallo/dkregistry-rs.git?rev=eb6349f2b99cd3dbd681d18d692a8c69e2e7b339)",

From 43f39e8beefaa817416454a7debd901e6a1dfb27 Mon Sep 17 00:00:00 2001
From: Luca Bruno <luca.bruno@coreos.com>
Date: Fri, 26 Jul 2019 15:10:48 +0000
Subject: [PATCH 3/3] graph-builder/metrics: track timestamp of last graph
 refresh

This instruments and tracks via metrics the timestamp of last
successful graph refresh.
---
 graph-builder/src/graph.rs | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/graph-builder/src/graph.rs b/graph-builder/src/graph.rs
index 89220103b..9856e8afa 100644
--- a/graph-builder/src/graph.rs
+++ b/graph-builder/src/graph.rs
@@ -31,6 +31,11 @@ lazy_static! {
         "Number of releases in the final graph, after processing"
     )
     .unwrap();
+    static ref GRAPH_LAST_SUCCESSFUL_REFRESH: IntGauge = IntGauge::new(
+        "graph_last_successful_refresh_timestamp",
+        "UTC timestamp of last successful graph refresh"
+    )
+    .unwrap();
     static ref GRAPH_UPSTREAM_RAW_RELEASES: IntGauge = IntGauge::new(
         "graph_upstream_raw_releases",
         "Number of releases fetched from upstream, before processing"
@@ -57,6 +62,7 @@ lazy_static! {
 pub fn register_metrics(registry: &prometheus::Registry) -> Fallible<()> {
     commons::register_metrics(&registry)?;
     registry.register(Box::new(GRAPH_FINAL_RELEASES.clone()))?;
+    registry.register(Box::new(GRAPH_LAST_SUCCESSFUL_REFRESH.clone()))?;
     registry.register(Box::new(GRAPH_UPSTREAM_RAW_RELEASES.clone()))?;
     registry.register(Box::new(UPSTREAM_ERRORS.clone()))?;
     registry.register(Box::new(UPSTREAM_SCRAPES.clone()))?;
@@ -249,21 +255,26 @@ pub fn run<'a>(settings: &'a config::AppSettings, state: &State) -> ! {
             }
         };
 
-        match serde_json::to_string(&graph) {
-            Ok(json) => {
-                *state.json.write() = json;
+        let json_graph = match serde_json::to_string(&graph) {
+            Ok(json) => json,
+            Err(err) => {
+                error!("Failed to serialize graph: {}", err);
+                continue;
+            }
+        };
 
-                if first_success {
-                    *state.ready.write() = true;
-                    first_success = false;
-                };
+        *state.json.write() = json_graph;
 
-                let nodes_count = graph.releases_count();
-                GRAPH_FINAL_RELEASES.set(nodes_count as i64);
-                debug!("graph update completed, {} valid releases", nodes_count);
-            }
-            Err(err) => error!("Failed to serialize graph: {}", err),
+        if first_success {
+            *state.ready.write() = true;
+            first_success = false;
         };
+
+        GRAPH_LAST_SUCCESSFUL_REFRESH.set(chrono::Utc::now().timestamp() as i64);
+
+        let nodes_count = graph.releases_count();
+        GRAPH_FINAL_RELEASES.set(nodes_count as i64);
+        debug!("graph update completed, {} valid releases", nodes_count);
     }
 }
 
