42 lines
1.1 KiB
Gleam
42 lines
1.1 KiB
Gleam
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)
|
|
}
|