1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! Session to channel-id map so approvals and resumed background results
//! route back to the channel the session was last handled in.
use uuid::Uuid;
use super::SlackState;
impl SlackState {
/// Record which channel_id corresponds to a given session, and the
/// thread its turn arrived in (#1988): `Some(ts)` lands the resume
/// reply in that thread, `None` means this turn was top-level and
/// clears any stale entry, so a channel-root conversation never gets
/// orphaned into an old thread.
pub async fn register_session_channel(
&self,
session_id: Uuid,
channel_id: String,
thread_ts: Option<String>,
) {
self.session_channels
.lock()
.await
.insert(session_id, channel_id.clone());
// Reverse ownership map (#148): written beside the forward map so the
// two cannot drift. Last writer wins - a channel re-registers to its
// newest owning session.
self.channel_sessions
.lock()
.await
.insert(channel_id, session_id);
// Thread map (#1988): same lockstep rule, third map.
match thread_ts {
Some(ts) => {
self.session_threads.lock().await.insert(session_id, ts);
}
None => {
self.session_threads.lock().await.remove(&session_id);
}
}
}
/// Look up the channel_id for a session.
pub async fn session_channel(&self, session_id: Uuid) -> Option<String> {
self.session_channels.lock().await.get(&session_id).cloned()
}
/// The thread a session's last inbound turn lived in (#1988), so the
/// background-resume reply lands where the conversation actually is.
/// `None` for top-level turns.
pub async fn session_thread(&self, session_id: Uuid) -> Option<String> {
self.session_threads.lock().await.get(&session_id).cloned()
}
/// Reverse lookup (#148): the session currently bound to a Slack channel id,
/// for `oc://slack/<id>` resolution. Reads the reverse map kept in lockstep
/// with the forward map at `register_session_channel`.
pub async fn session_owner_by_channel(&self, channel_id: &str) -> Option<Uuid> {
self.channel_sessions.lock().await.get(channel_id).copied()
}
}