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
- 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: Add search in pagers
- Add managesieve REPL binary for managesieve script management

View File

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

View File

@ -306,10 +306,19 @@ impl MailBackend for ImapType {
fn is_online_async(&self) -> ResultFuture<()> {
let connection = self.connection.clone();
Ok(Box::pin(async move {
let mut conn = connection.lock().await;
conn.connect().await?;
Ok(())
match timeout(std::time::Duration::from_secs(3), connection.lock()).await {
Ok(mut conn) => {
debug!("is_online_async");
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)
}
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();
}
}
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(MeliError::from(e).set_err_kind(crate::error::ErrorKind::Network));
}
@ -634,6 +631,7 @@ impl ImapConnection {
if let Err(err) =
try_await(async { self.stream.as_mut()?.send_command(command).await }).await
{
self.stream = Err(err.clone());
if err.kind.is_network() {
self.connect().await?;
}
@ -646,6 +644,7 @@ impl ImapConnection {
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
{
self.stream = Err(err.clone());
if err.kind.is_network() {
self.connect().await?;
}
@ -657,6 +656,7 @@ impl ImapConnection {
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 {
self.stream = Err(err.clone());
if err.kind.is_network() {
self.connect().await?;
}
@ -862,27 +862,12 @@ async fn read(
}
*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) => {
debug!(&conn.stream);
debug!(&e);
*err = Some(e.to_string());
*break_flag = true;
*prev_failure = Some(Instant::now());
}
}
None

View File

@ -66,7 +66,8 @@ impl BackendOp for ImapOp {
if !exists_in_cache {
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)
.await?;
conn.send_command(format!("UID FETCH {} (FLAGS RFC822)", uid).as_bytes())

View File

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

View File

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

View File

@ -903,9 +903,6 @@ async fn read_lines<'r>(
Ok(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) => {
return Err(MeliError::from(e).set_kind(crate::error::ErrorKind::Network));
}

View File

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

View File

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

View File

@ -1063,7 +1063,7 @@ impl fmt::Display for ProgressSpinner {
impl Component for ProgressSpinner {
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
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);
let stage = self.stage;
self.stage = (self.stage + 1).wrapping_rem(Self::KINDS[self.kind].len());