messua/minc

Messua Incoming.

The Incoming(state) type represents an incoming request bundled with a handle to the server’s state object.

fn handle(inc: Incoming(Int)) -> Outgoing {
  let cur_count = minc.alter_state(inc, fn(n) { n + 1 })
  let body =
    ["Your request is #", int.to_string(cur_count), ".\n"]
    |> string.concat()
  mout.ok()
  |> mout.with_string_body(body)
}

fn main() {
  messua.default()
  |> messua.with_state(1)
  |> messua.start(handle)
}
$ curl http://localhost:8080
Your request is #1.

$ curl http://localhost:8080
Your request is #2.

Types

A request bundled with some user-defined server state.

pub opaque type Incoming(state)

Values

pub fn get_state(inc: Incoming(state)) -> Result(state, Nil)

Get a handle to the Incoming’s bundled state.

fn handle_get_state(in: Incoming(String)) -> Outgoing {
  let assert Ok(state) = minc.get_state(in)
  io.println(state)
  mout.ok()
}

pub fn main() {
  messua.default()
  |> messua.with_state("Blue, feathery frog wings.")
  |> messua.start(handle_get_state)
}

// Prints "Blue, feathery frog wings." on every request.
pub fn get_then_update_state(
  inc: Incoming(state),
  with: fn(state) -> state,
) -> Result(state, Nil)

Update the server state with the supplied function, but return the value it had prior to the update.

This operation is “atomic” in the same sense as update_state().

pub fn req(
  inc: Incoming(state),
) -> request.Request(mist.Connection)

Get your grubby hands on the underlying incoming Request.

pub fn set_state(
  inc: Incoming(state),
  new_state: state,
) -> Incoming(state)

Sets the server state.

This is probably not the function you want to use. Note that, for example,

fn handle(in: Incoming(Int)) -> Outgoing {
  let state = minc.get_state(in)
  minc.set_state(in, state + 1)

  // ...
  mout.ok()
}

isn’t necessarily an atomic operation. If this handler is handling multiple requests concurrently, these state updates may step on each others’ toes.

You probably want update_state() instead.

pub fn update_state(
  inc: Incoming(state),
  with: fn(state) -> state,
) -> Nil

Update the server state with the given function.

This will update “atomically”, that is, this read-change-write compound operation is guaranteed to not overlap with any other read-change-write.

pub fn update_then_get_state(
  inc: Incoming(state),
  with: fn(state) -> state,
) -> Result(state, Nil)

Update the server state with the supplied function, then return the new value.

This operation is “atomic” in the same sense as update_state().

Search Document