Skip to main content

SessionRunner

Struct SessionRunner 

Source
pub struct SessionRunner<P: ConsensusPlugin, CP: ConversationPluginsFactory> {
    pub consensus: PluginConsensus<P>,
    /* private fields */
}

Fields§

§consensus: PluginConsensus<P>

Per-conversation consensus service. Owns this conversation’s scope in the shared storage and a private event bus. Constructed at conversation creation by User::build_consensus_service and held here so consensus calls hit the local service directly without User-level lookup. pub so integrators can reach session.consensus.event_bus().subscribe() for per-conv consensus event forwarding.

Implementations§

Source§

impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP>

Source

pub async fn initiate_proposal( arc: &Arc<RwLock<Self>>, request: ConversationUpdateRequest, creator_vote: CreatorVote, ) -> Result<(), UserError>

Start a consensus vote for request.

Gates against the session’s state machine (no proposals during Freezing/Selection, partial-freeze rules during Reelection, MLS must be attached), opens the consensus session inline, casts the creator’s vote (bundled YES) or registers an auto-vote (Deferred), and records a consensus_timeout deadline. The caller’s polling loop fires handle_consensus_timeout via Self::tick_deadlines once the deadline elapses.

creator_vote — see CreatorVote for wire shape and local UI behavior.

Source

pub async fn handle_incoming_update_request( arc: &Arc<RwLock<Self>>, request: ConversationUpdateRequest, ) -> Result<(), UserError>

Handle an incoming membership update (KP-derived InviteMember or RemoveMember): buffer it so every member has a durable record, then promote it to a voting proposal if this node is the current epoch steward and the conversation accepts new proposals.

Source

pub async fn process_user_vote( arc: &Arc<RwLock<Self>>, proposal_id: u32, vote: bool, ) -> Result<(), UserError>

Cast a manual vote on behalf of the local member. Blocked in Freezing and Selection; cancels any pending auto-vote so the manual choice wins.

Source

pub async fn tick_deadlines(arc: &Arc<RwLock<Self>>) -> Result<(), UserError>

Walk pending deadlines and fire any whose fire_at has elapsed. Call from the caller’s polling loop. Drains entries synchronously under a brief write guard, then awaits the async fire (consensus call or vote cast + publish) without holding the lock.

Source§

impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP>

Source

pub async fn apply_consensus_outcome( arc: &Arc<RwLock<Self>>, event: ConsensusEvent, ) -> Result<(), UserError>

Entry point from the consensus event bus: decode the proposal, apply the result to the conversation, and dispatch to the correct follow-up handler (election-accepted / election-rejected / emergency-scored).

Source§

impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP>

Source

pub fn check_pending_join( arc: &Arc<RwLock<Self>>, ) -> Result<PendingJoinTick, UserError>

Polling check for PendingJoin. Returns PendingJoinTick::Expired after emitting SessionEvent::Leaving once the pending-join window elapses; the caller handles registry-side cleanup.

Source

pub async fn poll_freeze_status( arc: &Arc<RwLock<Self>>, ) -> Result<(FreezeTimeoutStatus, DispatchOutcome), UserError>

Poll tick for Freezing: drives Freezing → Selection once candidates are all in or the freeze window elapses, then finalises, dispatches the resulting crate::core::ProcessResult, and returns the freeze status. The DispatchOutcome is LeaveRequested if the applied commit ejected the local member — the caller drives the User-side registry teardown.

Source

pub async fn check_member_freeze( arc: &Arc<RwLock<Self>>, ) -> Result<bool, UserError>

Drive the steward-inactivity check. Returns true exactly on the tick that transitions into Freezing; false while still waiting, outside Working, or when there’s no approved work. Stewards build their own commit candidate under the same lock; candidate-build failure is logged and the freeze transition proceeds (peers’ candidates still get processed).

Takes &Arc<RwLock<Self>> so the runner lock is released before awaiting on the transport for the steward’s own candidate send.

Source§

impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP>

Source

pub async fn send_kp_message( arc: &Arc<RwLock<Self>>, key_package: KeyPackageBytes, ) -> Result<(), UserError>

Broadcast key_package on this conversation’s welcome subtopic so the steward can invite us. The caller (typically the integrator) generates the key package via crate::app::User::generate_key_package — KP minting is identity-bound, not conversation-bound, so it stays at the User layer.

Takes &Arc<RwLock<Self>> so the runner lock is released before awaiting on the transport.

Source

pub async fn send_app_message( arc: &Arc<RwLock<Self>>, message: Vec<u8>, ) -> Result<(), UserError>

Send a chat message. Blocked in PendingJoin (no keys yet), Freezing, and Selection (epoch rotation in flight — the message might not decrypt on peers who have already merged the next commit). Governance traffic has its own gate (check_proposal_allowed).

Takes &Arc<RwLock<Self>> so the runner lock is released before awaiting on the transport.

Source

pub async fn process_ban_request( arc: &Arc<RwLock<Self>>, ban_request: BanRequest, ) -> Result<(), UserError>

Start a RemoveMember consensus round targeting ban_request.user_to_ban. The requester’s click means “I want this person removed” → the creator’s vote is bundled as YES at submit; no banner is shown to the requester.

Source§

impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP>

Source

pub fn get_conversation_state(&self) -> ConversationState

Source

pub fn get_epoch_and_retry(&self) -> Result<(u64, u32), UserError>

Current MLS epoch + reelection retry round. (0, 0) when the conversation has no MLS state yet (pending join). Intended for UI status display.

Source

pub fn get_pending_update_count(&self) -> usize

Count of buffered pending membership updates. Used by tests and the UI to verify buffer hygiene (e.g., that a joiner’s buffer is empty right after they receive the welcome).

Source

pub fn get_freeze_candidate_count(&self) -> (usize, usize)

Freeze round progress: (received, expected). Returns (0, 0) if not in freeze or no steward list is known.

Source

pub fn is_steward_for_self(&self) -> bool

Source

pub fn get_conversation_members(&self) -> Result<Vec<Vec<u8>>, UserError>

Identity bytes of every current member of this conversation, as reported by MLS. Returns an empty vec when the local user has no MLS state yet (pending join).

Source

pub fn get_member_scores(&self) -> Vec<(Vec<u8>, i64)>

Source

pub fn get_member_score(&self, member_id: &[u8]) -> Option<i64>

Source

pub fn get_pending_leave_identities(&self) -> Result<Vec<Vec<u8>>, UserError>

Identities that have an in-flight self-leave request. Used by the UI to render a “pending leave” indicator.

Source

pub fn get_member_roles(&self) -> Result<Vec<(Vec<u8>, MemberRole)>, UserError>

Steward role for each member. Uses live rotation so removed or pending-leave stewards are skipped in role display.

Source

pub fn get_approved_proposal_for_current_epoch( &self, ) -> Vec<ConversationUpdateRequest>

Source§

impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP>

Source

pub fn drain_events(&self) -> Vec<SessionEvent>

Drain every pending SessionEvent accumulated since the last call. Returns events in insertion order. Callers (UI fanout, audit log) invoke this once per polling cycle.

Source§

impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP>

Source

pub fn sync_scoring_members(&mut self, mls_members: &[Vec<u8>])

Add any MLS members not yet tracked in scoring, and drop scored entries for identities no longer in MLS. Diffing is delegated to scoring_member_diff; this method only applies the diff.

Source

pub async fn steward_list_housekeeping( arc: &Arc<RwLock<Self>>, ) -> Result<(), UserError>

Post-epoch-advance sequence: (1) auto-fill if membership dropped below sn_min, (2) kick off an election if the list is exhausted. Election-initiate failures are logged, not surfaced — conversation state may legitimately reject a new proposal right now.

Source

pub fn regenerate_steward_list(&mut self) -> Result<(), UserError>

Regenerate the steward list at the current epoch against the current MLS member set — same effect as a successful election. Intended for tests and administrative tooling.

Source

pub fn prune_pending_updates_after_commit(&mut self) -> Result<(), UserError>

Drop Add entries whose target is now a member and Remove entries whose target is now gone, then expire entries older than pending_update_max_epochs.

Source

pub async fn process_buffered_updates( arc: &Arc<RwLock<Self>>, ) -> Result<(), UserError>

On epoch advance, the new live epoch steward drains the pending-update buffer into voting proposals. Skips entries already covered by the current voting/approved queues so we don’t double-propose.

Source

pub async fn send_conversation_sync( arc: &Arc<RwLock<Self>>, ) -> Result<(), UserError>

Broadcast steward list + protocol config + peer scores + timing as an encrypted ConversationSync. Steward calls this after an Add-bearing commit so new joiners can fully participate. Idempotent for members who already have a steward list.

Takes &Arc<RwLock<Self>> so the runner lock is released before awaiting on the transport.

Source

pub async fn check_and_initiate_score_removals( arc: &Arc<RwLock<Self>>, ) -> Result<(), UserError>

Steward-only: file ScoreBelowThreshold ECPs for any member whose score fell at or below the removal threshold. Skips self and any target already covered by a pending removal.

Auto Trait Implementations§

§

impl<P, CP> !Freeze for SessionRunner<P, CP>

§

impl<P, CP> RefUnwindSafe for SessionRunner<P, CP>

§

impl<P, CP> Send for SessionRunner<P, CP>

§

impl<P, CP> Sync for SessionRunner<P, CP>

§

impl<P, CP> Unpin for SessionRunner<P, CP>

§

impl<P, CP> UnsafeUnpin for SessionRunner<P, CP>

§

impl<P, CP> UnwindSafe for SessionRunner<P, CP>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Classify for T

Source§

type Classified = T

Source§

fn classify(self) -> T

Source§

impl<T> Declassify for T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more