# 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 language.
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 it):
package main
import (
“github.com/apache/openwhisk-go-support"
)
func hello() (string, error) {
return "Hello Whisk!", nil
}
func main() {
openwhisk.Start(hello)
}
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
[email protected]