From 90b1602ad1c2d6a1c3836efb2dfe11d8157c2255 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Thu, 2 Mar 2017 22:27:23 -0500 Subject: [PATCH] Retry connect, and connect in parallel --- Cargo.lock | 31 ++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 55 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c060dc..40e7542 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,7 @@ dependencies = [ "mailparse 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "notify-rust 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "systray 0.1.1 (git+https://github.com/qdot/systray-rs.git?branch=linux-core)", "toml 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -158,6 +159,14 @@ dependencies = [ "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "deque" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.1" @@ -510,6 +519,14 @@ name = "num-traits" version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num_cpus" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "openssl" version = "0.8.3" @@ -635,6 +652,17 @@ dependencies = [ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rayon" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "0.2.1" @@ -886,6 +914,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum clang-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f98f0715ff67f27ca6a2f8f0ffc2a56f8edbc7acd57489c29eadc3a15c4eafe" "checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758" "checksum dbus 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58ec7b4cac6f79f36af1cd9cfdb9b935fc5a4e899f494ee03a3a6165f7d10b4b" +"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" @@ -923,6 +952,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" "checksum notify-rust 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "26508471f9e6ee12ebe949ece86ff01153e5d9a9ca331e0a6e9661502fb4e9a9" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" +"checksum num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18c392466409c50b87369414a2680c93e739aedeb498eb2bff7d7eb569744e2" "checksum openssl 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b11754cb6c81bb9e62faaf0eb6d94dde2aab0928c04db5078b74242880f35eb1" "checksum openssl-sys 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)" = "89c47ee94c352eea9ddaf8e364be7f978a3bb6d66d73176572484238dd5a5c3f" "checksum pango 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d25afdf2915e8afee5d0c2fccd8426b7c32e3a58aaf7ed2b41a4609c64617de" @@ -937,6 +967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quasi_codegen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b06172e92ab0099427609854ffb1512c377be5fc4beaf572ae5d5a01b8359596" "checksum quoted_printable 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebb55456d1e18dddfac0fedcc552ed3f690a645c5629b39e1a9d2ae544313178" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" +"checksum rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50c575b58c2b109e2fbc181820cbe177474f35610ff9e357dc75f6bac854ffbf" "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01" "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b" diff --git a/Cargo.toml b/Cargo.toml index 7019ab5..8be7e30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,4 @@ mailparse = "0.5.1" toml = "0.3.1" xdg = "2.0.0" notify-rust = "3.2.1" +rayon = "0.6.0" diff --git a/src/main.rs b/src/main.rs index e0f4a59..44c343c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ extern crate xdg; extern crate toml; extern crate imap; +extern crate rayon; extern crate openssl; extern crate systray; extern crate mailparse; @@ -8,10 +9,12 @@ extern crate notify_rust; use openssl::ssl::{SslContext, SslMethod}; use imap::client::Client; +use rayon::prelude::*; use std::collections::HashSet; use std::process::Command; use std::io::prelude::*; +use std::time::Duration; use std::sync::mpsc; use std::fs::File; use std::thread; @@ -122,23 +125,49 @@ fn main() { // TODO: w.set_tooltip(&"Whatever".to_string()); // TODO: app.wait_for_message(); - let accounts: Vec<_> = accounts.into_iter() + let accounts: Vec<_> = accounts.par_iter() .filter_map(|a| { - let name = a.name; - Client::secure_connect(a.server, SslContext::new(SslMethod::Sslv23).unwrap()) - .map(move |mut c| { - c.login(a.username, &a.password).unwrap(); - assert!(c.capability().unwrap().iter().any(|c| c == "IDLE")); - c.select("INBOX").unwrap(); - (String::from(name), c) - }) - .map_err(move |e| { - println!("Failed to connect account {}: {}", name, e); - }) - .ok() + let mut wait = 1; + for _ in 0..5 { + let c = Client::secure_connect(a.server, + SslContext::new(SslMethod::Sslv23).unwrap()) + .and_then(|mut c| { + try!(c.login(a.username, &a.password)); + let cap = try!(c.capability()); + if !cap.iter().any(|c| c == "IDLE") { + return Err(imap::error::Error::BadResponse(cap)); + } + try!(c.select("INBOX")); + Ok((String::from(a.name), c)) + }); + + match c { + Ok(c) => return Some(c), + Err(imap::error::Error::Io(e)) => { + println!("Failed to connect account {}: {}; retrying in {}s", + a.name, + e, + wait); + thread::sleep(Duration::from_secs(wait)); + } + Err(e) => { + println!("{} host produced bad IMAP tunnel: {}", a.name, e); + break; + } + } + + wait *= 2; + } + + None }) .collect(); + if accounts.is_empty() { + println!("No accounts in config worked; exiting..."); + return; + } + // We have now connected app.set_icon_from_file(&"/usr/share/icons/Faenza/stock/24/stock_connect.png".to_string()).ok();