openwhisk-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Carlos Santana <>
Subject Re: A proposal for a more efficient implementation of Go actions
Date Sat, 10 Feb 2018 15:52:02 GMT
TLDR; +1

On Sat, Feb 10, 2018 at 10:51 AM Carlos Santana <>

> I forgot to mention the use case were the user uploads source code .go
> action the /init will compiled it for them and then run the executable
> Like Rodric said also the whole proxy can be all golang and no python
> involved.
> — Carlos
> On Sat, Feb 10, 2018 at 10:47 AM Carlos Santana <>
> wrote:
>> Hi Michele
>> I’m not super familiar with go, but I think it goes inline with what we
>> do with.
>> So If I understand correctly your proposal is for the use case that user
>> provide and precompiled the executable.
>> One approach is for the web server that implements /init on port 8080 to
>> run the go executable the go executable in turn be a another web server
>> that implement the /run endpoint
>> One problem I see is the /run running on port 8080 there will be a port
>> conflict.
>> There could be different options
>> To avoid having use another port like 8081 this will required changes in
>> the invoker to know about.
>> I will try to avoid changes on the invoker to start
>> Another option is for the executable that implements the /run to tell the
>> server on /init to shutdown to release the port and then bind the web
>> server to port 8080 then from this point all the invokes will hit the /run
>> on the users executable action implementing the webserver.
>> This can be documented as the standard api for anyone to write this web
>> server executable.
>> This approach can be also be applicable to other compile languages like
>> Swift which I’m currently working which I’m currently implementing for
>> Swift 4.
>> I agree providing a user land library/package like you mentioned will be
>> an improvement if user want an easy way to implement the executable
>> implementing the webserver for the /run endpoint.
>> This is a good experiment and can be implemented today in user land using
>> docker action and quickly iterate and get feedback.
>> This approach can be implemented with modifications to the python proxy
>> to handle the /init but not the /run
>> Something that can be use for Swift to improve the mode of passing params
>> via stdin and last line of stdout and have memory with state and
>> connections and preserved improving performance.
>> Similar as the go library can be offer for Swift to implement the web
>> server wrapper.
>> And other languages :-)
>> I will let others shine in their point of view and other alternatives
>> Thank you for your interested in helping with Go support
>> — Carlos
>> On Sat, Feb 10, 2018 at 9:52 AM Michele Sciabarra <
>>> wrote:
>>> # 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 (
>>>         “"
>>> )
>>> 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

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message