Skip to content

Allow a max number of retries after a block fails #2157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions files/icons/awesome4.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pomodoro_break = "\uf0f4" # fa-coffee
pomodoro_paused = "\uf04c" # fa-pause
pomodoro_started = "\uf04b" # fa-play
pomodoro_stopped = "\uf04d" # fa-stop
refresh = "\uf021" # fa-refresh
resolution = "\uf096" # fa-square-o
scratchpad = "\uf2d2" # fa-window-restore
tasks = "\uf0ae" # fa-tasks
Expand Down
1 change: 1 addition & 0 deletions files/icons/awesome5.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pomodoro_break = "\uf0f4" # fa-coffee
pomodoro_paused = "\uf04c" # fa-pause
pomodoro_started = "\uf04b" # fa-play
pomodoro_stopped = "\uf04d" # fa-stop
refresh = "\uf021" # fa-sync
resolution = "\uf096" # fa-square-o
scratchpad = "\uf2d2" # fa-window-restore
tasks = "\uf0ae"
Expand Down
1 change: 1 addition & 0 deletions files/icons/awesome6.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pomodoro_break = "\uf0f4" # fa-coffee
pomodoro_paused = "\uf04c" # fa-pause
pomodoro_started = "\uf04b" # fa-play
pomodoro_stopped = "\uf04d" # fa-stop
refresh = "\uf021" # fa-arrows-rotate
resolution = "\uf096" # fa-square-o
scratchpad = "\uf2d2" # fa-window-restore
tasks = "\uf0ae"
Expand Down
1 change: 1 addition & 0 deletions files/icons/emoji.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pomodoro_break = "☕"
pomodoro_paused = "⏸️"
pomodoro_started = "▶️"
pomodoro_stopped = "⏹️"
refresh = "🔄"
resolution = "🔳"
scratchpad = "🗔"
tasks = "✅"
Expand Down
1 change: 1 addition & 0 deletions files/icons/material-nf.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pomodoro_break = "\U000f0176" # nf-md-coffee
pomodoro_paused = "\U000f03e4" # nf-md-pause
pomodoro_started = "\U000f040a" # nf-md-play
pomodoro_stopped = "\U000f04db" # nf-md-stop
refresh = "\U000f0450" # nf-md-refresh
resolution = "\U000f0293" # nf-md-fullscreen
scratchpad = "\U000f05b2" # nf-md-window_restore
tasks = "\U000f05c7" # nf-md-playlist_check
Expand Down
1 change: 1 addition & 0 deletions files/icons/material.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pomodoro_break = "\uefef" # coffee | TODO: broken?
pomodoro_paused = "\ue034" # pause
pomodoro_started = "\ue037" # play_arrow
pomodoro_stopped = "\uef6a" # play_disabled ef6a | TODO: broken?
refresh = "\ue5d5" # refresh
resolution = "\uf152" # crop-square-rounded
scratchpad = "\ue883" # flip_to_front
tasks = "\ue8f9" # work
Expand Down
42 changes: 37 additions & 5 deletions src/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//! `error_format` | Overrides global `error_format` | None
//! `error_fullscreen_format` | Overrides global `error_fullscreen_format` | None
//! `error_interval` | How long to wait until restarting the block after an error occurred. | `5`
//! `max_retries` | How many times should a block be restarted the block after an error occurred. If no limit is specified none will be enforced. | `None`
//! `[block.theme_overrides]` | Same as the top-level config option, but for this block only. Refer to `Themes and Icons` below. | None
//! `[block.icons_overrides]` | Same as the top-level config option, but for this block only. Refer to `Themes and Icons` below. | None
//! `[[block.click]]` | Set or override click action for the block. See below for details. | Block default / None
Expand Down Expand Up @@ -44,6 +45,8 @@ use crate::geolocator::{Geolocator, IPAddressInfo};
use crate::widget::Widget;
use crate::{BoxedFuture, Request, RequestCmd};

pub(super) const RESTART_BLOCK_BTN: &str = "restart_block_btn";

macro_rules! define_blocks {
{
$(
Expand Down Expand Up @@ -87,14 +90,37 @@ macro_rules! define_blocks {
$(#[cfg(feature = $feat)])?
#[allow(deprecated)]
Self::$block(config) => futures.push(async move {
while let Err(err) = $block::run(&config, &api).await {
if api.set_error(err).is_err() {
let mut error_count: u8 = 0;
while let Err(mut err) = $block::run(&config, &api).await {
let Ok(mut actions) = api.get_actions() else { return };
if api.set_default_actions(&[
(MouseButton::Left, Some(RESTART_BLOCK_BTN), "error_count_reset"),
]).is_err() {
return;
}
let should_retry = api
.max_retries
.map_or(true, |max_retries| error_count < max_retries);
if !should_retry {
err = Error {
message: Some("Block stopped, left click refresh icon to restart block".into()),
cause: Some(Arc::new(err)),
};
}
if api.set_error_with_restartable(err, !should_retry).is_err() {
return;
}
tokio::select! {
_ = tokio::time::sleep(api.error_interval) => (),
_ = tokio::time::sleep(api.error_interval), if should_retry => (),
Some(action) = actions.recv(), if !should_retry => match action.as_ref(){
"error_count_reset" => {
error_count = 0;
},
_ => (),
},
_ = api.wait_for_update_request() => (),
}
error_count = error_count.saturating_add(1);
}
}.boxed_local()),
)*
Expand Down Expand Up @@ -210,6 +236,7 @@ pub struct CommonApi {
pub(crate) request_sender: mpsc::UnboundedSender<Request>,
pub(crate) error_interval: Duration,
pub(crate) geolocator: Arc<Geolocator>,
pub(crate) max_retries: Option<u8>,
}

impl CommonApi {
Expand All @@ -233,12 +260,17 @@ impl CommonApi {
.error("Failed to send Request")
}

/// Sends the error to be displayed.
/// Sends the error to be displayed, no restart button will be shown.
pub fn set_error(&self, error: Error) -> Result<()> {
self.set_error_with_restartable(error, false)
}

/// Sends the error to be displayed.
pub fn set_error_with_restartable(&self, error: Error, restartable: bool) -> Result<()> {
self.request_sender
.send(Request {
block_id: self.id,
cmd: RequestCmd::SetError(error),
cmd: RequestCmd::SetError { error, restartable },
})
.error("Failed to send Request")
}
Expand Down
11 changes: 11 additions & 0 deletions src/blocks/packages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
//! [[block]]
//! block = "packages"
//! interval = 1800
//! error_interval = 300
//! max_retries = 5
//! package_manager = ["apt"]
//! format = " $icon $apt updates available"
//! format_singular = " $icon One update available "
Expand All @@ -103,6 +105,8 @@
//! block = "packages"
//! package_manager = ["pacman"]
//! interval = 600
//! error_interval = 300
//! max_retries = 5
//! format = " $icon $pacman updates available "
//! format_singular = " $icon $pacman update available "
//! format_up_to_date = " $icon system up to date "
Expand All @@ -124,6 +128,7 @@
//! package_manager = ["pacman", "aur"]
//! interval = 600
//! error_interval = 300
//! max_retries = 5
//! format = " $icon $pacman + $aur = $total updates available "
//! format_singular = " $icon $total update available "
//! format_up_to_date = " $icon system up to date "
Expand All @@ -139,6 +144,8 @@
//! block = "packages"
//! package_manager = ["dnf"]
//! interval = 1800
//! error_interval = 300
//! max_retries = 5
//! format = " $icon $dnf.eng(w:1) updates available "
//! format_singular = " $icon One update available "
//! format_up_to_date = " $icon system up to date "
Expand All @@ -156,6 +163,8 @@
//! block = "packages"
//! package_manager = ["xbps"]
//! interval = 1800
//! error_interval = 300
//! max_retries = 5
//! format = " $icon $xbps.eng(w:1) updates available "
//! format_singular = " $icon One update available "
//! format_up_to_date = " $icon system up to date "
Expand All @@ -174,6 +183,8 @@
//! block = "packages"
//! package_manager = ["apt", "pacman", "aur", "dnf", "xbps"]
//! interval = 1800
//! error_interval = 300
//! max_retries = 5
//! format = " $icon $apt + $pacman + $aur + $dnf + $xbps = $total updates available "
//! format_singular = " $icon One update available "
//! format_up_to_date = " $icon system up to date "
Expand Down
9 changes: 7 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,15 @@ impl Default for SharedConfig {
}

fn default_error_format() -> FormatConfig {
" {$short_error_message|X} ".parse().unwrap()
" {$restart_block_icon |}{$short_error_message|X} "
.parse()
.unwrap()
}

fn default_error_fullscreen() -> FormatConfig {
" $full_error_message ".parse().unwrap()
" {$restart_block_icon |}$full_error_message "
.parse()
.unwrap()
}

fn default_icons_format() -> Arc<String> {
Expand Down Expand Up @@ -108,6 +112,7 @@ pub struct CommonBlockConfig {
pub error_interval: u64,
pub error_format: FormatConfig,
pub error_fullscreen_format: FormatConfig,
pub max_retries: Option<u8>,

pub if_command: Option<String>,
}
Expand Down
1 change: 1 addition & 0 deletions src/icons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl Default for Icons {
"pomodoro_paused" => "PAUSED",
"pomodoro_started" => "STARTED",
"pomodoro_stopped" => "STOPPED",
"refresh" => "REFRESH",
"resolution" => "RES",
"scratchpad" => "[]",
"tasks" => "TSK",
Expand Down
40 changes: 28 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use futures::stream::{FuturesUnordered, StreamExt as _};
use tokio::process::Command;
use tokio::sync::{Notify, mpsc};

use crate::blocks::{BlockAction, BlockError, CommonApi};
use crate::blocks::{BlockAction, BlockError, CommonApi, RESTART_BLOCK_BTN};
use crate::click::{ClickHandler, MouseButton};
use crate::config::{BlockConfigEntry, Config, SharedConfig};
use crate::errors::*;
Expand Down Expand Up @@ -131,7 +131,7 @@ struct Request {
enum RequestCmd {
SetWidget(Widget),
UnsetWidget,
SetError(Error),
SetError { error: Error, restartable: bool },
SetDefaultActions(&'static [(MouseButton, Option<&'static str>, &'static str)]),
SubscribeToActions(mpsc::UnboundedSender<BlockAction>),
}
Expand Down Expand Up @@ -186,6 +186,10 @@ impl Block {
}

fn set_error(&mut self, fullscreen: bool, error: Error) {
self.set_error_with_restartable(fullscreen, false, error);
}

fn set_error_with_restartable(&mut self, fullscreen: bool, restartable: bool, error: Error) {
let error = BlockError {
block_id: self.id,
block_name: self.name,
Expand All @@ -202,6 +206,7 @@ impl Block {
widget.set_values(map! {
"full_error_message" => Value::text(error.to_string()),
[if let Some(v) = &error.error.message] "short_error_message" => Value::text(v.to_string()),
[if restartable] "restart_block_icon" => Value::icon("refresh").with_instance(RESTART_BLOCK_BTN),
});
self.state = BlockState::Error { widget };
}
Expand Down Expand Up @@ -270,6 +275,7 @@ impl BarState {
request_sender: self.request_sender.clone(),
error_interval: Duration::from_secs(block_config.common.error_interval),
geolocator: self.config.geolocator.clone(),
max_retries: block_config.common.max_retries,
};

let error_format = block_config
Expand Down Expand Up @@ -325,8 +331,12 @@ impl BarState {
self.fullscreen_block = None;
}
}
RequestCmd::SetError(error) => {
block.set_error(self.fullscreen_block == Some(request.block_id), error);
RequestCmd::SetError { error, restartable } => {
block.set_error_with_restartable(
self.fullscreen_block == Some(request.block_id),
restartable,
error,
);
}
RequestCmd::SetDefaultActions(actions) => {
block.default_actions = actions;
Expand Down Expand Up @@ -414,16 +424,22 @@ impl BarState {
}
}
BlockState::Error { widget } => {
if self.fullscreen_block == Some(event.id) {
self.fullscreen_block = None;
widget.set_format(block.error_format.clone());
if let Some((_, _, action)) = block.default_actions
.iter()
.find(|(btn, widget, _)| *btn == event.button && *widget == event.instance.as_deref()) {
block.send_action(Cow::Borrowed(action));
} else {
self.fullscreen_block = Some(event.id);
widget.set_format(block.error_fullscreen_format.clone());
if self.fullscreen_block == Some(event.id) {
self.fullscreen_block = None;
widget.set_format(block.error_format.clone());
} else {
self.fullscreen_block = Some(event.id);
widget.set_format(block.error_fullscreen_format.clone());
}
block.notify_intervals(&self.widget_updates_sender);
self.render_block(event.id)?;
self.render();
}
block.notify_intervals(&self.widget_updates_sender);
self.render_block(event.id)?;
self.render();
}
}
}
Expand Down