Packages
Session management library for Wisp. Manage user sessions in a simple key-value store.
Current section
Files
Jump to
Current section
Files
src/memory_store.gleam
import gleam/dict
import gleam/erlang/process
import gleam/option
import gleam/otp/actor
import gleam/result
import wisp_kv_sessions/session
import wisp_kv_sessions/session_config
const timeout = 3000
type Message(element) {
Shutdown
GetSession(
reply_with: process.Subject(Result(session.Session, Nil)),
session_id: session.SessionId,
)
SetSession(
reply_with: process.Subject(session.Session),
session: session.Session,
)
DeleteSession(session_id: session.SessionId)
}
type Db =
dict.Dict(session.SessionId, session.Session)
pub fn try_create_session_store() {
use db <- result.map(
actor.start(dict.new(), handle_message)
|> result.replace_error(session.DbSetupError),
)
session_config.SessionStore(
default_expiry: 60 * 60,
get_session: get_session(db),
save_session: save_session(db),
delete_session: delete_session(db),
)
}
fn get_session(db: process.Subject(Message(a))) {
fn(session_id: session.SessionId) {
Ok(
process.call(db, GetSession(_, session_id), timeout)
|> result.map(fn(session) { option.Some(session) })
|> option.from_result
|> option.flatten,
)
}
}
fn save_session(db: process.Subject(Message(a))) {
fn(session: session.Session) {
Ok(process.call(db, SetSession(_, session), timeout))
}
}
fn delete_session(db: process.Subject(Message(a))) {
fn(session_id: session.SessionId) {
process.send(db, DeleteSession(session_id))
Ok(Nil)
}
}
fn handle_message(message: Message(e), db: Db) -> actor.Next(Message(e), Db) {
case message {
Shutdown -> actor.Stop(process.Normal)
GetSession(client, session_id) -> {
let session = dict.get(db, session_id)
process.send(client, session)
actor.continue(db)
}
SetSession(client, session) -> {
process.send(client, session)
actor.continue(dict.insert(db, session.id, session))
}
DeleteSession(session_id) -> {
actor.continue(dict.delete(db, session_id))
}
}
}