Overview

  wrk supports executing a LuaJIT script during three distinct phases: setup,
  running, and done. Each wrk thread has an independent scripting environment
  and the setup & done phases execute in a separate environment which does
  not participate in the running phase.

  The public Lua API consists of a global table and a number of global
  functions:

  wrk = {
    scheme  = "http",
    host    = "localhost",
    port    = nil,
    method  = "GET",
    path    = "/",
    headers = {},
    body    = nil,
    thread  = <userdata>,
  }

  function wrk.format(method, path, headers, body)

    wrk.format returns a HTTP request string containing the passed parameters
    merged with values from the wrk table.

  function wrk.lookup(host, service)

    wrk.lookup returns a table containing all known addresses for the host
    and service pair. This corresponds to the POSIX getaddrinfo() function.

  function wrk.connect(addr)

    wrk.connect returns true if the address can be connected to, otherwise
    it returns false. The address must be one returned from wrk.lookup().

  The following globals are optional, and if defined must be functions:

    global setup    -- called during thread setup
    global init     -- called when the thread is starting
    global request  -- called to generate the HTTP request
    global delay    -- called to get the request delay
    global response -- called with HTTP response header and body
                       (body does not contain actual response data if
                         the command line option --lua-dont-pass-body is used)
    global done     -- called with results of run

Setup

  function setup(thread)

  The setup phase begins after the target IP address has been resolved and all
  threads have been initialized but not yet started.

  setup() is called once for each thread and receives a userdata object
  representing the thread. setup() is called in the global LUA context.

    thread.addr             - get or set the thread's server address
    thread:get(name)        - get the value of a global in the thread's env
    thread:set(name, value) - set the value of a global in the thread's env
    thread:stop()           - stop the thread

  Only boolean, nil, number, wrk.addr, and string values or tables of the same
  may be transfered via get()/set() and thread:stop() can only be called while
  the thread is running.

Running

  The following functions are called in a privte per-thread LUA context. Each
  context corresponds to an entry in the 'thread' table passed to setup().

  function init(args)
  function delay()
  function request()
  function response(status, headers, body)

  The running phase begins with a single call to init(), followed by
  a call to request() and response() for each request cycle.

  The init() function receives any extra command line arguments for the
  script which must be separated from wrk arguments with "--".

  delay() returns the number of milliseconds to delay sending the next
  request.

  request() returns a string containing the HTTP request. Building a new
  request each time is expensive, when testing a high performance server
  one solution is to pre-generate all requests in init() and do a quick
  lookup in request().

  response() is called with the HTTP response status and headers.
  Parsing the headers is expensive, so if the response global is
  nil after the call to init() wrk will ignore the headers and body.
  Using wrk's --lua-dont-pass-body command line option will cause a "dummy"
  body to be passed instead of the actual body. The option is useful for
  benchmarking endpoints which pass large response bodies.

  teardown() is called without arguments after the run concluded.
Done

  function done(summary, latency, requests)

  done() is called in the global LUA context.

  The done() function receives a table containing result data, and two
  statistics objects representing the per-request latency and per-thread
  request rate. Duration and latency are microsecond values and rate is
  measured in requests per second.

  latency.min              -- minimum value seen
  latency.max              -- maximum value seen
  latency.mean             -- average value seen
  latency.stdev            -- standard deviation
  latency:percentile(99.0) -- 99th percentile value
  latency(i)               -- raw value and count

  summary = {
    duration = N,  -- run duration in microseconds
    requests = N,  -- total completed requests
    bytes    = N,  -- total bytes received
    errors   = {
      connect = N, -- total socket connection errors
      read    = N, -- total socket read errors
      write   = N, -- total socket write errors
      status  = N, -- total HTTP status codes > 399
      timeout = N  -- total request timeouts
    }
  }
