import app/web import gleam/erlang/process import gleam/otp/actor pub const call_timeout = 1000 pub type Manager(resp_type, resp_error, msg_type) { Manager(subject: process.Subject(Request(resp_type, resp_error, msg_type))) } pub type State(state_type) { State(ctx: web.Context, state: state_type) } pub type Response(resp_type, resp_error) = Result(resp_type, resp_error) pub type Request(resp_type, resp_error, msg_type) { Request( reply_to: process.Subject(Response(resp_type, resp_error)), msg: msg_type, ) } pub fn new( ctx: web.Context, init_state: fn() -> state_type, handle: fn(Request(resp_type, resp_error, msg_type), State(state_type)) -> actor.Next(Request(resp_type, resp_error, msg_type), State(state_type)), ) -> Manager(resp_type, resp_error, msg_type) { let assert Ok(subject) = actor.start(State(ctx, init_state()), handle) Manager(subject) } pub fn call( manager: Manager(resp_type, resp_error, msg_type), msg: msg_type, ) -> Result(resp_type, resp_error) { actor.call(manager.subject, Request(_, msg), call_timeout) }