Open hawkw opened 10 months ago
part of #11, maybe?
some thoughts about this emerged fully-formed into my head while going for a run in the rain today:
we could just make the "get service list from registry" be a normal MGNP service like:
pub struct ServiceList;
impl registry::Service for ServiceList {
type Hello = ();
type ConnectError = ();
type ClientMsg = EnumerateRequest;
type ServerMsg = EnumerateChunk;
const UUID = /* .. */.;
}
#[derive(Serialize, Deserialize, Debug)]
pub enum EnumerateRequest {
All,
// this is an enum to carve out possible space for
// "give me only some specific services" type requests later
}
#[derive(Serialize, Deserialize, Debug)]
pub struct EnumerateChunk {
// actual service list.
pub services: heapless::Vec<ServiceBinding, 32>;
// the current number of this chunk. the intent here is to allow
// pagination by the service registry so that we can use `heapless::Vec`s
pub chunk_num: usize,
// total number of chunks
pub total_chunks: usize,
// alternatively we could just have a "is_last: bool", but i thought sending
// total number of chunks was nicer, since it allows the client to e.g.
// preallocate enough storage for all the service mappings, or whatever...
}
// maps a service type UUID to an identity that implements that service.
// this could, alternatively, have been a tuple, but i thought we might
// want to retain the ability to add additional metadata later.
#[derive(Serialize, Deserialize, Debug)]
pub struct ServiceBinding {
pub uuid: Uuid,
pub identity: registry::Identity,
}
i wonder if the message pagination design i sketched out in https://github.com/tosc-rs/mgnp/issues/27#issuecomment-1817298425 could be easily pulled out into a reusable utility (possibly as part of #25)...
something like this:
#[derive(Serialize, Deserialize, Debug)]
pub struct Page<T, const LEN: usize = 32> {
/// The data for this page.
pub body: heapless::Vec<T, LEN>,
/// Total number of pages in this response.
pub page_total: usize,
/// This page's page number.
///
/// If this is equal to `page_total`, then this is the last
/// page in the response.
pub page_number: usize,
}
impl<T, const LEN: usize> Page<T, LEN> {
pub fn from_iter(i: impl Iterator<Item = T> + ExactSizeIterator) -> impl Iterator<Item = Self> {
// ...
}
}
currently, clients can attempt to remote services with a known identity. however, there's no way to look up the list of services available in the remote registry.
we should maybe add some kind of mechanism for enumerating a list of available service identities on the remote. this could be our first actual use of connection ID zero for link-control messages.
eventually this mechanism could be used to gossip routing tables for multi-hop routing.