Files
fn-serverless/docs/hot-functions.md
Reed Allman 4839edc12b add default to idle_timeout in hot fn docs (#309)
it's a bit funny that in hot / not functions idle_timeout appears but it's not such a big deal, either
2017-09-08 09:58:42 -07:00

3.0 KiB

Hot functions

Oracle Functions is built on top of container technologies, for each incoming workload, it spins a new container, feed it with the payload and sends the answer back to the caller. You can expect an average start time of 300ms per container. You may refer to this blog post to understand the details better.

In the case you need faster start times for your function, you may use a hot container instead.

hot functions are started once and kept alive while there is incoming workload. Thus, it means that once you decide to use a hot function, you must be able to tell the moment it should reading from standard input to start writing to standard output.

Currently, Functions implements a HTTP-like protocol to operate hot containers, but instead of communication through a TCP/IP port, it uses standard input/output.

Implementing a hot function

In the examples directory, there is one simple implementation of a hot function which we are going to get in the details here.

The basic cycle comprises three steps: read standard input up to a previosly known point, process the work, the write the output to stdout with some information about when functions daemon should stop reading from stdout.

In the case at hand, we serve a loop, whose first part is plugging stdin to a HTTP request parser:

r := bufio.NewReader(os.Stdin)
req, err := http.ReadRequest(r)

// ...
} else {
	l, _ := strconv.Atoi(req.Header.Get("Content-Length"))
	p := make([]byte, l)
	r.Read(p)
}

Note how Content-Length is used to help determinate how far standard input must be read.

The next step in the cycle is to do some processing:

	//...
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "Hello %s\n", p)
	for k, vs := range req.Header {
		fmt.Fprintf(&buf, "ENV: %s %#v\n", k, vs)
	}
	//...

And finally, we return the result with a Content-Length header, so Functions daemon would know when to stop reading the gotten response.

res := http.Response{
	Proto:      "HTTP/1.1",
	ProtoMajor: 1,
	ProtoMinor: 1,
	StatusCode: 200,
	Status:     "OK",
}
res.Body = ioutil.NopCloser(&buf)
res.ContentLength = int64(buf.Len())
res.Write(os.Stdout)

Rinse and repeat for each incoming workload.

Enabling a hot function

In your func.yaml, add "format: http". That's it.

format (mandatory) either "default" or "http". If "http", then it is a hot container.

idle_timeout (optional) - idle timeout (in seconds) before function termination, default 30 seconds.