Skip to content
This repository was archived by the owner on Dec 22, 2019. It is now read-only.
This repository was archived by the owner on Dec 22, 2019. It is now read-only.

Make Middleware Async by Default #17

@leostera

Description

@leostera

After talking with @ulrikstrid about having an async router, it makes a lot of sense that the default middleware stack works asynchronously.

The first step is fairly straightforward, we just need to parametrize the Middleware stack with an io('a) type. Then the runner of the stack will get passed a sequencing function (>>=). Voila, all middleware is now async.

The interesting bit to me is how to make it flexible enough to allow for middleware that will define how the rest of the stack unfolds.

For example:

server
|> use(Middleware.log)
|> use(Router.with_handler(handler))
|> Lwt_main.run;

This would log before routing, and then return a response. But what would need to happen to allow for log to actually log the response status and response time?

The above right now behaves like:

  1. Log stuff
  2. Route and reply

Whereas I'd like the async behavior to allow for:

  1. Begin Measuring time
  2. Route and reply
  3. Log time between 1 and now

Without changing the way the middleware stack was built. In other words, the definition of the Middleware.log middleware would have to look a little more like:

let log = (ctx, next) => {
  let time_1 = Time.now();
  next() >>= (result => {
   let time_2 = Time.now();
   Log.debug( m => m("%f.3ms", time_2 -. time_1);
   result
  });
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions