1use anyhow::Result;
2pub use greentic_session::{SessionData, SessionKey};
3use greentic_session::{SessionStore, inmemory::InMemorySessionStore};
4use greentic_types::{TenantCtx, UserId};
5use std::sync::Arc;
6
7#[derive(Clone)]
9pub struct SharedSessionStore {
10 inner: Arc<InMemorySessionStore>,
11}
12
13pub async fn store_from_env() -> Result<SharedSessionStore> {
15 Ok(shared_memory_store())
16}
17
18pub fn shared_memory_store() -> SharedSessionStore {
20 SharedSessionStore {
21 inner: Arc::new(InMemorySessionStore::new()),
22 }
23}
24
25impl SharedSessionStore {
26 pub async fn find_by_user(
28 &self,
29 ctx: &TenantCtx,
30 user: &UserId,
31 ) -> Result<Option<(SessionKey, SessionData)>> {
32 let waits = self.inner.list_waits_for_user(ctx, user)?;
33 match waits.len() {
34 0 => Ok(None),
35 1 => {
36 let key = waits.into_iter().next().expect("single wait entry");
37 let data = self
38 .inner
39 .get_session(&key)?
40 .ok_or_else(|| anyhow::anyhow!("session not found for wait"))?;
41 Ok(Some((key, data)))
42 }
43 _ => Err(anyhow::anyhow!(
44 "multiple waits exist for user; use scope-based routing instead"
45 )),
46 }
47 }
48
49 pub async fn create_session(&self, ctx: &TenantCtx, data: SessionData) -> Result<SessionKey> {
51 self.inner.create_session(ctx, data).map_err(Into::into)
52 }
53
54 pub async fn update_session(&self, key: &SessionKey, data: SessionData) -> Result<()> {
56 self.inner.update_session(key, data).map_err(Into::into)
57 }
58}