Remove two useless comments.
[stakingWatchdogWatchdog.git] / src / main.rs
index c7791a0..9944ae1 100644 (file)
@@ -1,4 +1,5 @@
 use std::{
+    fmt,
     net::UdpSocket,
     thread,
     time::{self, Duration},
@@ -79,8 +80,9 @@ fn main() -> Result<()> {
                     // Send e-mail.
                     println!("Sending email...");
                     match send_email(
-                        "Watchdog Watchdog ERROR",
-                        &format!("Error: {:?}", error),
+                        "Watchdog Watchdog: Check alive error",
+                        &format!("Error: {}", error),
+                        &config.smtp_relay_address,
                         &config.smtp_login,
                         &config.smtp_password,
                     ) {
@@ -110,41 +112,71 @@ enum PingError {
     WrongMessageReceived(String),
 }
 
+impl fmt::Display for PingError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            PingError::SocketReceiveError(error) => {
+                write!(f, "Didn't receive any response from watchdog: {}", error)
+            }
+            PingError::SocketSendError(error) => {
+                write!(f, "Unable to send the message: {}", error)
+            }
+            PingError::WrongMessageReceived(message) => {
+                write!(f, "Watchdog replay with a wrong message: {}", message)
+            }
+        }
+    }
+}
+
 fn ping(socket: &UdpSocket, rng: &mut ThreadRng) -> std::result::Result<Duration, PingError> {
-    let number: u64 = rng.gen();
-    let mut buffer = number.to_le_bytes();
-
-    let now = time::Instant::now();
-    match socket.send(&buffer) {
-        Ok(_size_sent) => {
-            buffer.fill(0);
-            match socket.recv(&mut buffer) {
-                Ok(size_received) => {
-                    if size_received == 8 {
-                        let number_received = u64::from_le_bytes(buffer);
-                        if number_received != number {
+    loop {
+        let number: u64 = rng.gen();
+        let mut buffer = number.to_le_bytes();
+        let now = time::Instant::now();
+        match socket.send(&buffer) {
+            Ok(_size_sent) => {
+                buffer.fill(0);
+                match socket.recv(&mut buffer) {
+                    Ok(size_received) => {
+                        if size_received == 8 {
+                            let number_received = u64::from_le_bytes(buffer);
+                            if number_received == number {
+                                return Ok(time::Instant::now() - now);
+                            } else {
+                                return Err(PingError::WrongMessageReceived(format!(
+                                    "Message number receceived ({}) is not equal to the one sent ({})",
+                                    number_received, number
+                                )));
+                            }
+                        } else {
                             return Err(PingError::WrongMessageReceived(format!(
-                                "Message number receceived ({}) is not equal to the one sent ({})",
-                                number_received, number
+                                "Size of packet must be 8, received size: {}",
+                                size_received
                             )));
                         }
-                    } else {
-                        return Err(PingError::WrongMessageReceived(format!(
-                            "Size of packet must be 8, received size: {}",
-                            size_received
-                        )));
                     }
+                    // FIXME.
+                    // Test the kind because sometime 'recv' returns
+                    // '(Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }'.
+                    // Try again in this case.
+                    Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => {
+                        println!("WouldBlock error: {}", error)
+                    }
+                    Err(error) => return Err(PingError::SocketReceiveError(error)),
                 }
-                Err(error) => return Err(PingError::SocketReceiveError(error)),
             }
+            Err(error) => return Err(PingError::SocketSendError(error)),
         }
-        Err(error) => return Err(PingError::SocketSendError(error)),
     }
-
-    Ok(time::Instant::now() - now)
 }
 
-fn send_email(title: &str, body: &str, login: &str, pass: &str) -> Result<()> {
+fn send_email(
+    title: &str,
+    body: &str,
+    smtp_relay_address: &str,
+    login: &str,
+    pass: &str,
+) -> Result<()> {
     let email = Message::builder()
         .message_id(None)
         .from("Staking Watchdog Watchdog <redmine@d-lan.net>".parse()?)
@@ -155,12 +187,10 @@ fn send_email(title: &str, body: &str, login: &str, pass: &str) -> Result<()> {
 
     let creds = Credentials::new(login.to_string(), pass.to_string());
 
-    // Open a remote connection to gmail
-    let mailer = SmtpTransport::relay("mail.gandi.net")?
+    let mailer = SmtpTransport::relay(smtp_relay_address)?
         .credentials(creds)
         .build();
 
-    // Send the email
     let response = mailer.send(&email)?;
 
     println!("{:?}", response);