pub(crate) struct SlackSubsystemHost(Weak<Workspace>);Expand description
The SlackHost one pump drives: a Weak<Workspace> behind the port,
so the workspace can drop while a pump runs and every port call then
degrades to a no-op.
Tuple Fields§
§0: Weak<Workspace>Implementations§
Trait Implementations§
Source§impl SlackHost for SlackSubsystemHost
impl SlackHost for SlackSubsystemHost
Source§fn client(
&self,
workspace: &str,
timeout: Duration,
) -> Result<Arc<dyn SlackApi>, String>
fn client( &self, workspace: &str, timeout: Duration, ) -> Result<Arc<dyn SlackApi>, String>
A ready API for this workspace, or an error when the workspace is
not configured. The host builds it, so the token stays with the
workspace and the connector never asks for the credential itself.
The trait object is what the pump drives, so a test host can hand
back a double instead of a live client.
Source§fn user_id(&self, workspace: &str) -> Option<String>
fn user_id(&self, workspace: &str) -> Option<String>
The authenticated user’s id for a workspace, resolved at boot.
Needed to recognise
<@U...> mentions.Source§fn user_name(&self, workspace: &str, user: &str) -> Option<String>
fn user_name(&self, workspace: &str, user: &str) -> Option<String>
The display name this workspace has already resolved for a user id,
or
None when it has not. A users.info lookup is a call, so the
host keeps what it has learned rather than the sweep re-asking for
every message from a known author.Source§fn set_user_name(&self, workspace: &str, user: &str, name: &str)
fn set_user_name(&self, workspace: &str, user: &str, name: &str)
Record a user’s display name, so the next message from them is free.
Source§fn subscriptions(&self, workspace: &str) -> Vec<SlackSubscription>
fn subscriptions(&self, workspace: &str) -> Vec<SlackSubscription>
The subscriptions scoped to one workspace.
Source§fn watermark(
&self,
workspace: &str,
conversation: &str,
) -> Result<Option<String>, String>
fn watermark( &self, workspace: &str, conversation: &str, ) -> Result<Option<String>, String>
The last timestamp delivered for a conversation, or
None when it
has never been swept. An error means the cursor could not be read:
the caller skips the conversation rather than sweeping it from the
beginning, which would deliver its whole history as new.Source§fn set_watermark(&self, workspace: &str, conversation: &str, ts: &str)
fn set_watermark(&self, workspace: &str, conversation: &str, ts: &str)
Record the last timestamp delivered. A
ts is a string with a
microsecond fraction; never round-trip it through a number.Source§fn followed_threads(
&self,
workspace: &str,
conversation: &str,
) -> Vec<SlackFollowedThread>
fn followed_threads( &self, workspace: &str, conversation: &str, ) -> Vec<SlackFollowedThread>
The threads tracked for a conversation, each with the owners still
subscribed to it. The host prunes while listing: an owner whose
subscription is gone is dropped from the record, a row’s last owner
deletion removes the row, and a row idle past the host’s drop age
never comes back.
Source§fn thread_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Result<Option<String>, String>
fn thread_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> Result<Option<String>, String>
How far a thread’s replies have been read: normally the newest reply
seen, and nothing at all before the first walk. An error means the
cursor could not be read: the caller skips the thread this tick
rather than walking it from the parent.
Source§fn set_thread_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
ts: &str,
)
fn set_thread_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ts: &str, )
Advance a thread’s reply cursor. It is compared as a string, and the
per-tick read sends one microsecond below it as the walk’s
oldest -
see just_below - so a reply at the cursor is re-read for an edit.Source§fn mark_thread_participating(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
)
fn mark_thread_participating( &self, workspace: &str, conversation: &str, parent_ts: &str, )
Record that the user is in a thread, so later walks read past the
cursor instead of reading the thread whole to find out again.
Source§fn thread_full_read_at(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Option<Instant>
fn thread_full_read_at( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> Option<Instant>
When this thread was last read whole, if it ever was. The attempt
is stamped whether or not the read lands, so a thread that errors or
is past the page cap backs off instead of retrying every tick.
Source§fn mark_thread_full_read(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
at: Instant,
)
fn mark_thread_full_read( &self, workspace: &str, conversation: &str, parent_ts: &str, at: Instant, )
Record a whole-thread read attempt at
at.Source§fn thread_first_walk(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> bool
fn thread_first_walk( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> bool
Whether this thread’s next walk is its first since the row was
created. Peek, not take: a throttled or failed first walk must
keep the mark, or the replay guard is lost for the row’s life. A first
walk filters by
ts alone: its seed is latest_reply, which an edit
does not move, so an edit-aware filter would hand over corrections the
previous row already had.Source§fn clear_thread_first_walk(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
)
fn clear_thread_first_walk( &self, workspace: &str, conversation: &str, parent_ts: &str, )
Clear the first-walk mark, once that walk has actually read the thread.
Source§fn thread_edit_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Option<String>
fn thread_edit_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> Option<String>
The newest edit stamp a whole read has already judged. A whole read
tests
edited against this, never against the reply cursor: the cheap
tick moves the cursor to the newest reply, and an edit below it would
otherwise be behind the cursor forever. Durable with the thread
row, not process state: a restart that lost it would judge every
edited reply against nothing and re-offer corrections already
delivered.Source§fn set_thread_edit_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
ts: &str,
)
fn set_thread_edit_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ts: &str, )
Advance a thread’s edit watermark to
ts.Whether this is the first time an author lookup has failed for this
user. The lookup is retried either way; this only decides whether the
failure is worth a line a reader sees, since a persistent one - a
token missing
users:read, a network that is down - would otherwise
report itself for every author on every tick.Source§fn first_draft_user_failure(&self, workspace: &str, user: &str) -> bool
fn first_draft_user_failure(&self, workspace: &str, user: &str) -> bool
The same once-per-user line for a held draft’s tag lookup. Kept apart
from
Self::first_author_failure so a draft’s miss does not spend
the line the sweep relies on, and the sweep’s does not hide the draft’s.Source§fn follow_thread(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
owner: SlackThreadOwner,
since: &str,
)
fn follow_thread( &self, workspace: &str, conversation: &str, parent_ts: &str, owner: SlackThreadOwner, since: &str, )
Track a thread, owned by the matching subscription. A new row’s cursor
starts at
since, which the caller picks to be recent enough to
survive the idle window and below everything still worth delivering.
Tracking again by another owner adds that owner and keeps the cursor.Source§fn set_connected(&self, workspace: &str, connected: bool)
fn set_connected(&self, workspace: &str, connected: bool)
Liveness for the Inspector’s status line.
Source§fn name_conversation(&self, workspace: &str, conversation: &str, name: &str)
fn name_conversation(&self, workspace: &str, conversation: &str, name: &str)
Fill in a conversation’s display name on any subscription that has
none, so the Inspector can render the name rather than the raw id.
Only unnamed records are touched: a conversation renamed since it
was subscribed keeps the stored name.
Source§fn auto_subscribe(&self, workspace: &str, message: &SlackMessage) -> bool
fn auto_subscribe(&self, workspace: &str, message: &SlackMessage) -> bool
Called after a mention is delivered, so the conversation it came
from is watched too and the agent can reply into it rather than
only seeing the ping. Returns whether a record was added: the host
does nothing when that owner already covers the conversation.
Source§fn own_post(&self, workspace: &str, conversation: &str, ts: &str) -> bool
fn own_post(&self, workspace: &str, conversation: &str, ts: &str) -> bool
Whether forge posted this message itself, read from the outbound
ledger by its ts. This is what the sweep refuses: forge posts as
the user, so the author says nothing about who wrote the words.
Source§fn post_in_flight(
&self,
workspace: &str,
conversation: &str,
) -> Option<Duration>
fn post_in_flight( &self, workspace: &str, conversation: &str, ) -> Option<Duration>
How long the oldest live post call in
conversation has been in
flight, or None when none is. A message can reach history before
the post call returns and its ts is ledgered, so the sweep skips
the conversation for the tick instead of delivering its own post.
A mark older than REQUEST_TIMEOUT is the host’s to expire,
never something to obey.Source§fn deliver(
&self,
subscription: &SlackSubscription,
messages: &[SlackMessage],
) -> bool
fn deliver( &self, subscription: &SlackSubscription, messages: &[SlackMessage], ) -> bool
Hand one conversation’s matched messages to its subscriber’s
session, as the one block they will be read as. Returns whether
delivery succeeded: a
false means the caller did not advance the
conversation cursor past this batch, so the next sweep re-delivers
it instead of losing it.Auto Trait Implementations§
impl !RefUnwindSafe for SlackSubsystemHost
impl !UnwindSafe for SlackSubsystemHost
impl Freeze for SlackSubsystemHost
impl Send for SlackSubsystemHost
impl Sync for SlackSubsystemHost
impl Unpin for SlackSubsystemHost
impl UnsafeUnpin for SlackSubsystemHost
Blanket Implementations§
§impl<T> AnySync for T
impl<T> AnySync for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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