Small fixes

memfd
Manos Pitsidianakis 2020-07-29 14:33:09 +03:00
parent 44fdc0765e
commit 3ac2c12e7a
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
11 changed files with 48 additions and 35 deletions

View File

@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Add `select` command to select threads that match search query
- Add support for mass copying/deleting/flagging/moving of messages
- IMAP: add support for COMPRESS=DEFLATE and others
Extension use can be configured with individual flags such as `use_deflate`
- Rename EXECUTE mode to COMMAND
- add async IMAP backend
- add in-app SMTP support
- ui: Show decoded source by default when viewing an Envelope's source - ui: Show decoded source by default when viewing an Envelope's source
- ui: Add search in pagers - ui: Add search in pagers
- Add managesieve REPL binary for managesieve script management - Add managesieve REPL binary for managesieve script management

View File

@ -65,7 +65,7 @@ quote = "^1.0"
proc-macro2 = "1.0.18" proc-macro2 = "1.0.18"
[profile.release] [profile.release]
lto = true lto = "fat"
opt-level = "z" opt-level = "z"
debug = false debug = false

View File

@ -306,10 +306,19 @@ impl MailBackend for ImapType {
fn is_online_async(&self) -> ResultFuture<()> { fn is_online_async(&self) -> ResultFuture<()> {
let connection = self.connection.clone(); let connection = self.connection.clone();
Ok(Box::pin(async move { Ok(Box::pin(async move {
let mut conn = connection.lock().await; match timeout(std::time::Duration::from_secs(3), connection.lock()).await {
conn.connect().await?; Ok(mut conn) => {
debug!("is_online_async");
Ok(()) match debug!(timeout(std::time::Duration::from_secs(3), conn.connect()).await) {
Ok(Ok(())) => Ok(()),
Err(err) | Ok(Err(err)) => {
conn.stream = Err(err.clone());
debug!(conn.connect().await)
}
}
}
Err(err) => Err(err),
}
})) }))
} }
@ -1627,3 +1636,15 @@ async fn fetch_hlpr(
}; };
Ok(payload) Ok(payload)
} }
use futures::future::{self, Either};
async fn timeout<O>(dur: std::time::Duration, f: impl Future<Output = O>) -> Result<O> {
futures::pin_mut!(f);
match future::select(f, smol::Timer::after(dur)).await {
Either::Left((out, _)) => Ok(out),
Either::Right(_) => {
Err(MeliError::new("Timed out.").set_kind(crate::error::ErrorKind::Network))
}
}
}

View File

@ -396,9 +396,6 @@ impl ImapStream {
last_line_idx += pos + "\r\n".len(); last_line_idx += pos + "\r\n".len();
} }
} }
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => { Err(e) => {
return Err(MeliError::from(e).set_err_kind(crate::error::ErrorKind::Network)); return Err(MeliError::from(e).set_err_kind(crate::error::ErrorKind::Network));
} }
@ -634,6 +631,7 @@ impl ImapConnection {
if let Err(err) = if let Err(err) =
try_await(async { self.stream.as_mut()?.send_command(command).await }).await try_await(async { self.stream.as_mut()?.send_command(command).await }).await
{ {
self.stream = Err(err.clone());
if err.kind.is_network() { if err.kind.is_network() {
self.connect().await?; self.connect().await?;
} }
@ -646,6 +644,7 @@ impl ImapConnection {
pub async fn send_literal(&mut self, data: &[u8]) -> Result<()> { pub async fn send_literal(&mut self, data: &[u8]) -> Result<()> {
if let Err(err) = try_await(async { self.stream.as_mut()?.send_literal(data).await }).await if let Err(err) = try_await(async { self.stream.as_mut()?.send_literal(data).await }).await
{ {
self.stream = Err(err.clone());
if err.kind.is_network() { if err.kind.is_network() {
self.connect().await?; self.connect().await?;
} }
@ -657,6 +656,7 @@ impl ImapConnection {
pub async fn send_raw(&mut self, raw: &[u8]) -> Result<()> { pub async fn send_raw(&mut self, raw: &[u8]) -> Result<()> {
if let Err(err) = try_await(async { self.stream.as_mut()?.send_raw(raw).await }).await { if let Err(err) = try_await(async { self.stream.as_mut()?.send_raw(raw).await }).await {
self.stream = Err(err.clone());
if err.kind.is_network() { if err.kind.is_network() {
self.connect().await?; self.connect().await?;
} }
@ -862,27 +862,12 @@ async fn read(
} }
*prev_failure = None; *prev_failure = None;
} }
Err(e)
if e.kind() == std::io::ErrorKind::WouldBlock
|| e.kind() == std::io::ErrorKind::Interrupted =>
{
debug!(&e);
if let Some(prev_failure) = prev_failure.as_ref() {
if Instant::now().duration_since(*prev_failure)
>= std::time::Duration::new(60 * 5, 0)
{
*err = Some(e.to_string());
*break_flag = true;
}
} else {
*prev_failure = Some(Instant::now());
}
}
Err(e) => { Err(e) => {
debug!(&conn.stream); debug!(&conn.stream);
debug!(&e); debug!(&e);
*err = Some(e.to_string()); *err = Some(e.to_string());
*break_flag = true; *break_flag = true;
*prev_failure = Some(Instant::now());
} }
} }
None None

View File

@ -66,7 +66,8 @@ impl BackendOp for ImapOp {
if !exists_in_cache { if !exists_in_cache {
let mut response = String::with_capacity(8 * 1024); let mut response = String::with_capacity(8 * 1024);
{ {
let mut conn = connection.lock().await; let mut conn =
timeout(std::time::Duration::from_secs(3), connection.lock()).await?;
conn.examine_mailbox(mailbox_hash, &mut response, false) conn.examine_mailbox(mailbox_hash, &mut response, false)
.await?; .await?;
conn.send_command(format!("UID FETCH {} (FLAGS RFC822)", uid).as_bytes()) conn.send_command(format!("UID FETCH {} (FLAGS RFC822)", uid).as_bytes())

View File

@ -155,7 +155,7 @@ impl Collection {
new_hash: EnvelopeHash, new_hash: EnvelopeHash,
mailbox_hash: MailboxHash, mailbox_hash: MailboxHash,
) -> bool { ) -> bool {
if !self.envelopes.write().unwrap().contains_key(&old_hash) { if !self.envelopes.read().unwrap().contains_key(&old_hash) {
return false; return false;
} }
let mut envelope = self.envelopes.write().unwrap().remove(&old_hash).unwrap(); let mut envelope = self.envelopes.write().unwrap().remove(&old_hash).unwrap();

View File

@ -75,6 +75,7 @@ impl AccountSettings {
#[serde(default)] #[serde(default)]
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MailboxConf { pub struct MailboxConf {
#[serde(alias = "rename")]
pub alias: Option<String>, pub alias: Option<String>,
#[serde(default = "false_val")] #[serde(default = "false_val")]
pub autoload: bool, pub autoload: bool,

View File

@ -903,9 +903,6 @@ async fn read_lines<'r>(
Ok(b) => { Ok(b) => {
ret.push_str(unsafe { std::str::from_utf8_unchecked(&buf[0..b]) }); ret.push_str(unsafe { std::str::from_utf8_unchecked(&buf[0..b]) });
} }
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
panic!("block");
}
Err(e) => { Err(e) => {
return Err(MeliError::from(e).set_kind(crate::error::ErrorKind::Network)); return Err(MeliError::from(e).set_kind(crate::error::ErrorKind::Network));
} }

View File

@ -384,7 +384,7 @@ impl StatusPanel {
.enumerate() .enumerate()
{ {
write_string_to_grid( write_string_to_grid(
&format!("{}: {}", f.path(), f.special_usage()), &format!("{}: {}", f.special_usage(), f.path()),
&mut self.content, &mut self.content,
self.theme_default.fg, self.theme_default.fg,
self.theme_default.bg, self.theme_default.bg,

View File

@ -733,12 +733,10 @@ impl ThreadView {
let total_rows = height!(area); let total_rows = height!(area);
let pager_ratio = context.runtime_settings.pager.pager_ratio; let pager_ratio = context.runtime_settings.pager.pager_ratio;
let bottom_entity_rows = (pager_ratio * total_rows) / 100; let mut bottom_entity_rows = (pager_ratio * total_rows) / 100;
if bottom_entity_rows > total_rows { if bottom_entity_rows > total_rows {
clear_area(grid, area, crate::conf::value(context, "theme_default")); bottom_entity_rows = total_rows.saturating_sub(1);
context.dirty_areas.push_back(area);
return;
} }
let mut mid = get_y(upper_left) + total_rows - bottom_entity_rows; let mut mid = get_y(upper_left) + total_rows - bottom_entity_rows;
@ -952,6 +950,9 @@ impl Component for ThreadView {
self.dirty = false; self.dirty = false;
return; return;
} }
if !self.is_dirty() {
return;
}
/* If user has selected another mail to view, change to it */ /* If user has selected another mail to view, change to it */
if self.new_expanded_pos != self.expanded_pos { if self.new_expanded_pos != self.expanded_pos {

View File

@ -1063,7 +1063,7 @@ impl fmt::Display for ProgressSpinner {
impl Component for ProgressSpinner { impl Component for ProgressSpinner {
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
if self.dirty { if self.dirty {
let theme_attr = crate::conf::value(context, "theme_default"); let theme_attr = crate::conf::value(context, "status.bar");
clear_area(grid, area, theme_attr); clear_area(grid, area, theme_attr);
let stage = self.stage; let stage = self.stage;
self.stage = (self.stage + 1).wrapping_rem(Self::KINDS[self.kind].len()); self.stage = (self.stage + 1).wrapping_rem(Self::KINDS[self.kind].len());