pub struct IdAllocator { /* private fields */ }Expand description
Maps stable identities onto wire identifiers until a channel is withdrawn.
Session entries live forever because an official client keeps its own user
across migrations. Channel entries do not: once any client has accepted a
ChannelRemove, that wire identifier is dead even if the same semantic
channel later returns. Retiring a mapping never recycles its number because
the allocation cursor only moves forward.
§Why one allocator serves the whole runtime
Allocating per shard looks natural - a shard owns its subtree - and it is wrong as soon as a connection can move between shards. The client keys its model on the wire id, so shard A withdrawing channel 5 and shard B later creating its own channel 5 is, from the client’s seat, one identifier coming back as a different thing. Sessions are worse: the official client refuses to remove itself from its model, so a migrating connection that changed session would be a second user forever.
Keying channels on (shard, key) and sessions on Occupant fixes both at
once. A migration keeps its session for free, because the occupant did not
change.
REF: references/mumble/src/mumble/Messages.cpp : MainWindow::msgUserRemove
ends with if (pDst != pSelf) pmModel->removeUser(pDst);.
Implementations§
Source§impl IdAllocator
impl IdAllocator
Sourcepub fn new() -> IdAllocator
pub fn new() -> IdAllocator
A fresh allocator. Channel ids start at 1: zero is the runtime’s root.
Sourcepub fn channel(
&mut self,
shard: ShardId,
key: ChannelKey,
) -> Result<ChannelId, Exhausted>
pub fn channel( &mut self, shard: ShardId, key: ChannelKey, ) -> Result<ChannelId, Exhausted>
The id for key within shard, allocating one the first time it is seen.
§Errors
Exhausted::Channels once every id has been handed out.
Sourcepub fn session(&mut self, occupant: Occupant) -> Result<SessionId, Exhausted>
pub fn session(&mut self, occupant: Occupant) -> Result<SessionId, Exhausted>
The session for occupant, allocating one the first time it is seen.
§Errors
Exhausted::Sessions once every session has been handed out.
Sourcepub fn allocated_session(&self, occupant: Occupant) -> Option<SessionId>
pub fn allocated_session(&self, occupant: Occupant) -> Option<SessionId>
The session already allocated for occupant, without allocating.
Sourcepub fn allocated_channel(
&self,
shard: ShardId,
key: ChannelKey,
) -> Option<ChannelId>
pub fn allocated_channel( &self, shard: ShardId, key: ChannelKey, ) -> Option<ChannelId>
The id already allocated for key within shard, without allocating.
What a lookup outside a render needs: asking IdAllocator::channel
there would hand out an id for a key nothing rendered, and an id handed
out is an id spent for the life of the runtime.
Sourcepub fn retain_channels(
&mut self,
shard: ShardId,
retained: &BTreeSet<ChannelKey>,
)
pub fn retain_channels( &mut self, shard: ShardId, retained: &BTreeSet<ChannelKey>, )
Retire every channel identity from shard that the accepted render no
longer contains.
Removing the mapping does not recycle its numeric id: next_channel
only moves forward. If the same semantic key returns later, it therefore
receives a fresh id, as required after the client has observed a
ChannelRemove.
Sourcepub fn retire_channel_ids(
&mut self,
shard: ShardId,
retired: &BTreeSet<ChannelId>,
)
pub fn retire_channel_ids( &mut self, shard: ShardId, retired: &BTreeSet<ChannelId>, )
Retire channel ids one client has accepted as removed.