use anyhow::Result;
pub use greentic_session::{SessionData, SessionKey};
use greentic_session::{SessionStore, inmemory::InMemorySessionStore};
use greentic_types::{TenantCtx, UserId};
use std::sync::Arc;
#[derive(Clone)]
pub struct SharedSessionStore {
inner: Arc<InMemorySessionStore>,
}
pub async fn store_from_env() -> Result<SharedSessionStore> {
Ok(shared_memory_store())
}
pub fn shared_memory_store() -> SharedSessionStore {
SharedSessionStore {
inner: Arc::new(InMemorySessionStore::new()),
}
}
impl SharedSessionStore {
pub async fn find_by_user(
&self,
ctx: &TenantCtx,
user: &UserId,
) -> Result<Option<(SessionKey, SessionData)>> {
let waits = self.inner.list_waits_for_user(ctx, user)?;
match waits.len() {
0 => Ok(None),
1 => {
let key = waits.into_iter().next().expect("single wait entry");
let data = self
.inner
.get_session(&key)?
.ok_or_else(|| anyhow::anyhow!("session not found for wait"))?;
Ok(Some((key, data)))
}
_ => Err(anyhow::anyhow!(
"multiple waits exist for user; use scope-based routing instead"
)),
}
}
pub async fn create_session(&self, ctx: &TenantCtx, data: SessionData) -> Result<SessionKey> {
self.inner.create_session(ctx, data).map_err(Into::into)
}
pub async fn update_session(&self, key: &SessionKey, data: SessionData) -> Result<()> {
self.inner.update_session(key, data).map_err(Into::into)
}
}