TLDR; +1 On Sat, Feb 10, 2018 at 10:51 AM Carlos Santana <[email protected]> wrote:
> 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 <[email protected]> > 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 < >> [email protected]> 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 ( >>> “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] >>> >>
