From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pdm-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id F3B341FF15C for <inbox@lore.proxmox.com>; Fri, 18 Apr 2025 09:46:54 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 2EFD937ACE; Fri, 18 Apr 2025 09:46:52 +0200 (CEST) From: Dominik Csapak <d.csapak@proxmox.com> To: pdm-devel@lists.proxmox.com Date: Fri, 18 Apr 2025 09:46:47 +0200 Message-Id: <20250418074647.1057147-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.39.5 MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.022 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pdm-devel] [PATCH datacenter-manager v2] ui: resource tree: use AsyncAbortGuard to cancel obsolete pending loads X-BeenThere: pdm-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Datacenter Manager development discussion <pdm-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pdm-devel>, <mailto:pdm-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pdm-devel/> List-Post: <mailto:pdm-devel@lists.proxmox.com> List-Help: <mailto:pdm-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel>, <mailto:pdm-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox Datacenter Manager development discussion <pdm-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pdm-devel-bounces@lists.proxmox.com Sender: "pdm-devel" <pdm-devel-bounces@lists.proxmox.com> Currently, if a new serach term is given, a new load will occur if the INPUT_BUFFER_MS time is reached. Any old in-flight API requests are not canceled, and might still arrive. To prevent that, use an AsyncAbortGuard so the old load will be aborted whenever it is overwritten. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- changes from v1: * use AsyncAbortGuard instead of AsyncPool, since that's the correct abstraction here. * introduce a new Msg variant, so that we can overwrite the AsyncAbortGuard in the update method replaces: https://lore.proxmox.com/pdm-devel/20250416113232.2488103-1-d.csapak@proxmox.com/ ui/src/widget/resource_tree.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/ui/src/widget/resource_tree.rs b/ui/src/widget/resource_tree.rs index feff308..ddfd7cb 100644 --- a/ui/src/widget/resource_tree.rs +++ b/ui/src/widget/resource_tree.rs @@ -18,6 +18,7 @@ use pwt::{ }, ActionIcon, Column, Container, Fa, Panel, Progress, Row, Tooltip, }, + AsyncAbortGuard, }; use pwt_macros::{builder, widget}; @@ -88,6 +89,7 @@ async fn load_resources(search_term: String) -> Result<Vec<RemoteResources>, Err } pub enum Msg { + LoadRequest, Load, LoadResult(Result<Vec<RemoteResources>, Error>), RemoteListChanged(RemoteList), @@ -101,6 +103,7 @@ pub struct PdmResourceTree { _context_listener: ContextHandle<RemoteList>, selection: Selection, _load_timeout: Option<Timeout>, + _load_guard: Option<AsyncAbortGuard>, } impl PdmResourceTree {} @@ -117,7 +120,7 @@ impl Component for PdmResourceTree { .expect("No Remote list context provided"); if !props.search_only || !props.search_term.is_empty() { - ctx.link().clone().send_message(Msg::Load); + ctx.link().clone().send_message(Msg::LoadRequest); } let store = TreeStore::new().view_root(false); @@ -131,25 +134,32 @@ impl Component for PdmResourceTree { _context_listener, selection, _load_timeout: None, + _load_guard: None, } } fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool { match msg { - Msg::Load => { + Msg::LoadRequest => { let props = ctx.props(); let link = ctx.link().clone(); - let search_term = props.search_term.clone(); - if props.search_only && !search_term.is_empty() { + if props.search_only && !props.search_term.is_empty() { self._load_timeout = Some(Timeout::new(INPUT_BUFFER_MS, move || { - link.send_future(async move { - Msg::LoadResult(load_resources(search_term).await) - }); + link.send_message(Msg::Load); })); self.loading = true; } true } + Msg::Load => { + let props = ctx.props(); + let link = ctx.link().clone(); + let search_term = props.search_term.clone(); + self._load_guard = Some(AsyncAbortGuard::spawn(async move { + link.send_message(Msg::LoadResult(load_resources(search_term).await)) + })); + false + } Msg::LoadResult(res) => { match res { Ok(result) => { @@ -189,7 +199,7 @@ impl Component for PdmResourceTree { let reload = self.remote_list.len() != list.len(); self.remote_list = list; if reload && !self.remote_list.is_empty() { - ctx.link().send_message(Msg::Load); + ctx.link().send_message(Msg::LoadRequest); } true } @@ -200,7 +210,7 @@ impl Component for PdmResourceTree { let props = ctx.props(); if props.search_term != old_props.search_term { if !props.search_only || !props.search_term.is_empty() { - ctx.link().clone().send_message(Msg::Load); + ctx.link().clone().send_message(Msg::LoadRequest); } else if props.search_term.is_empty() { // clear grid ctx.link() -- 2.39.5 _______________________________________________ pdm-devel mailing list pdm-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel