Skip to content

Commit 90b1602

Browse files
committed
Retry connect, and connect in parallel
1 parent d4e3e91 commit 90b1602

3 files changed

Lines changed: 74 additions & 13 deletions

File tree

Cargo.lock

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ mailparse = "0.5.1"
2323
toml = "0.3.1"
2424
xdg = "2.0.0"
2525
notify-rust = "3.2.1"
26+
rayon = "0.6.0"

src/main.rs

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
extern crate xdg;
22
extern crate toml;
33
extern crate imap;
4+
extern crate rayon;
45
extern crate openssl;
56
extern crate systray;
67
extern crate mailparse;
78
extern crate notify_rust;
89

910
use openssl::ssl::{SslContext, SslMethod};
1011
use imap::client::Client;
12+
use rayon::prelude::*;
1113

1214
use std::collections::HashSet;
1315
use std::process::Command;
1416
use std::io::prelude::*;
17+
use std::time::Duration;
1518
use std::sync::mpsc;
1619
use std::fs::File;
1720
use std::thread;
@@ -122,23 +125,49 @@ fn main() {
122125
// TODO: w.set_tooltip(&"Whatever".to_string());
123126
// TODO: app.wait_for_message();
124127

125-
let accounts: Vec<_> = accounts.into_iter()
128+
let accounts: Vec<_> = accounts.par_iter()
126129
.filter_map(|a| {
127-
let name = a.name;
128-
Client::secure_connect(a.server, SslContext::new(SslMethod::Sslv23).unwrap())
129-
.map(move |mut c| {
130-
c.login(a.username, &a.password).unwrap();
131-
assert!(c.capability().unwrap().iter().any(|c| c == "IDLE"));
132-
c.select("INBOX").unwrap();
133-
(String::from(name), c)
134-
})
135-
.map_err(move |e| {
136-
println!("Failed to connect account {}: {}", name, e);
137-
})
138-
.ok()
130+
let mut wait = 1;
131+
for _ in 0..5 {
132+
let c = Client::secure_connect(a.server,
133+
SslContext::new(SslMethod::Sslv23).unwrap())
134+
.and_then(|mut c| {
135+
try!(c.login(a.username, &a.password));
136+
let cap = try!(c.capability());
137+
if !cap.iter().any(|c| c == "IDLE") {
138+
return Err(imap::error::Error::BadResponse(cap));
139+
}
140+
try!(c.select("INBOX"));
141+
Ok((String::from(a.name), c))
142+
});
143+
144+
match c {
145+
Ok(c) => return Some(c),
146+
Err(imap::error::Error::Io(e)) => {
147+
println!("Failed to connect account {}: {}; retrying in {}s",
148+
a.name,
149+
e,
150+
wait);
151+
thread::sleep(Duration::from_secs(wait));
152+
}
153+
Err(e) => {
154+
println!("{} host produced bad IMAP tunnel: {}", a.name, e);
155+
break;
156+
}
157+
}
158+
159+
wait *= 2;
160+
}
161+
162+
None
139163
})
140164
.collect();
141165

166+
if accounts.is_empty() {
167+
println!("No accounts in config worked; exiting...");
168+
return;
169+
}
170+
142171
// We have now connected
143172
app.set_icon_from_file(&"/usr/share/icons/Faenza/stock/24/stock_connect.png".to_string()).ok();
144173

0 commit comments

Comments
 (0)