From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 21EC31FF0B2 for ; Mon, 24 Aug 2026 15:13:25 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id C94A82158F; Mon, 24 Aug 2026 15:13:24 +0200 (CEST) Content-Type: text/plain; charset=UTF-8 Date: Mon, 24 Aug 2026 15:13:20 +0200 Message-Id: Subject: Re: [PATCH proxmox 01/20] router: introduce shared state From: "Lukas Wagner" To: "Robert Obkircher" , "Lukas Wagner" Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Mailer: aerc 0.21.0-0-g5549850facc2-dirty References: <20260817125727.454039-1-l.wagner@proxmox.com> <20260817125727.454039-2-l.wagner@proxmox.com> <178732075530.242959.4186982857535541130.b4-review@b4> In-Reply-To: <178732075530.242959.4186982857535541130.b4-review@b4> X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1787577170795 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.665 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: AUGZ6PABXDYTBWVKP4JYA4BUL32D64ZO X-Message-ID-Hash: AUGZ6PABXDYTBWVKP4JYA4BUL32D64ZO X-MailFrom: l.wagner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: pdm-devel@lists.proxmox.com X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On Fri Aug 21, 2026 at 3:59 PM CEST, Robert Obkircher wrote: >> +use anyhow::{Error, bail}; >> + >> +/// Registry of state values, keyed by their type. >> +/// >> +/// It holds at most one value per type. Values are registered with >> +/// [`register`](SharedStateRegistry::register) before the registry is = handed over to the API >> +/// environment, from where handlers can access them through >> +/// [`RpcEnvironment::shared_state`](crate::RpcEnvironment::shared_stat= e). This allows passing >> +/// application context to handlers without resorting to globals. >> +#[derive(Default)] >> +pub struct SharedStateRegistry { >> + map: HashMap>, >> +} > > We could get rid of some indirection by replacing the map with a > Box<&dyn SharedState>. Probably not worth it, though. Yeah, the map lookups happen once per API request, so I don't think the indirection should be an issue here -- performance-wise at least. The current approach has in my opinion the advantage that it keeps the type-id magic contained within proxmox-router. With the trait-based approach, if I understand it correctly, the application code would need to perform the cast from dyn Any. Now, given that this is handled behind the scenes by the API macro, it should not matter that much, probably. > > trait SharedState { fn lookup(&self, id: TypeId) -> &dyn Any; } > > struct PdmState { a: A, b: B } > > impl SharedState for PdmState { > fn lookup(&self, id: TypeId) -> &dyn Any { > if id =3D=3D TypeId::of::() { &self.a } > else if id =3D=3D TypeId::of::() { &self.b } > else { unreachable!() } > } > } > > >> + >> +impl SharedStateRegistry { >> + /// Get a clone of the registered value of type `T`, if there is on= e. >> + pub fn lookup(&self) -> Option= { >> + self.map >> + .get(&TypeId::of::()) >> + .and_then(|s| s.downcast_ref()) >> + .cloned() > This could .expect("value must have correct type for key"). Makes sense, as a failed cast is clearly a bug here. Thanks!