openwhisk-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michele Sciabarra <>
Subject A proposal for a more efficient implementation of Go actions
Date Sat, 10 Feb 2018 14:52:13 GMT
# How Go Action are currently implemented

Currently, Go Action are implemented using the generic docker support. 

I investigated the implementation and I found there is a python based server, listening for
/init and /run requests. The /init will collect an executable and place in the current folder,
while the /run will invoke the executable with popen, feeding the input and returning the
output as log, and the last line as the result as a serialized json.

The problem is spawning a new process for each request sound like a revival of the CGI.  I
made some investigation and it is certainly not the most efficient implementation.  Basically
everyone moved from CGI executing processes to servers listening  fro requests since many
many years ago.

Also I investigated how AWS Lambda supports go, and as I suspected it is a completely different
story: they implements a server in Go listening and serving requests. 

The problem here is Python and Node are dynamic scripting languages, while Go is a compiled
I checked also how Node and Python runtimes work: they are all servers, they receive the code
of the function, “eval" the code and then execute it for serving requests. 

Go, generating an executable, cannot afford to do that. We cannot “eval” precompiled code.
But it is also inefficient to spawn a new process for each function invocation. 

The solution here is to exec only once, when the runtime receive the executable of the function,
at the /init time. Then you should replace the main executable and  serve the /run requests
directly in the replaced executable. Of course this means that the replaced executable should
be able to serve the /init requests too. All of this should go in a library

# My proposal.

Support for Go should look like to the following (very similar to Lambda support, I admit

package main

import (

func hello() (string, error) {
        return "Hello Whisk!", nil

func main() {

The magic will be inside the library.

The Start function will start a web server listening for two requests.

Posts to /run will invoke some deserialisation code and then invoke the function.

Posts to /init will receive an executable, unzip it, look for an "exec" file and then exec
to it (expecting of course the server itself is implemented using the same library).  

A new Go specific runtime will built easily using the same library. Maybe with a default action
retuning an error.

If the proposal sounds acceptable I volunteer to implement it.

  Michele Sciabarra

View raw message