1- use crate :: { db:: save_kv, model:: schedule:: UnixTimestamp } ;
1+ use std:: time:: Duration ;
2+
3+ use crate :: {
4+ db:: { load_kv, save_kv} ,
5+ model:: schedule:: UnixTimestamp ,
6+ } ;
7+ use human_time:: ToHumanTimeString ;
28use tracing:: { error, info} ;
39
410const KEY : & str = "HEARTBEAT" ;
@@ -20,7 +26,39 @@ pub fn start_heartbeat(db_pool: sqlx::PgPool) {
2026 } ) ;
2127}
2228
23- pub fn time_since_last_heartbeat ( db_pool : sqlx:: PgPool ) -> String {
24- // TODO 1: Get last heartbeat from DB
25- "First run" . to_string ( )
29+ pub async fn last_heartbeat_info ( db_pool : sqlx:: PgPool ) -> String {
30+ match load_kv ( & db_pool, KEY ) . await {
31+ Some ( db_value) => match UnixTimestamp :: from_db_fmt ( & db_value) {
32+ Ok ( last_heartbeat) => {
33+ let Ok ( now) = UnixTimestamp :: now ( ) else {
34+ return format ! (
35+ "Last Heartbeat: {last_heartbeat} but Failed to get current timestamp"
36+ ) ;
37+ } ;
38+ let seconds_since_last_heartbeat = now. 0 - last_heartbeat. 0 ;
39+ if seconds_since_last_heartbeat < 0 {
40+ return format ! (
41+ "Last heartbeat in the future?! Last heartbeat: {last_heartbeat}, Now: {now}"
42+ ) ;
43+ }
44+ let Ok ( seconds_since_last_heartbeat) = seconds_since_last_heartbeat. try_into ( )
45+ else {
46+ // Invalid u64
47+ return format ! (
48+ "Invalid u64!!! Seconds since heartbeat: {seconds_since_last_heartbeat}, Last heartbeat: {last_heartbeat}, Now: {now}"
49+ ) ;
50+ } ;
51+ let downtime = Duration :: from_secs ( seconds_since_last_heartbeat) ;
52+ format ! (
53+ "Downtime: {}\n Last Heartbeat: {last_heartbeat}\n Now: {now}" ,
54+ downtime. to_human_time_string( )
55+ )
56+ }
57+ Err ( err) => {
58+ error ! ( ?err) ;
59+ "Error Loading Last Heartbeat" . to_string ( )
60+ }
61+ } ,
62+ None => "First run" . to_string ( ) ,
63+ }
2664}
0 commit comments