Skip to content

Native / Docker runtime does not reuse variables outside of main function in Golang #5044

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jonee opened this issue Jan 9, 2021 · 6 comments

Comments

@jonee
Copy link

jonee commented Jan 9, 2021

Environment details:

  • IBM Cloud Functions
  • Docker / Native runtime

Steps to reproduce the issue:

  1. Create the action with the code below
  2. Retrieve the web action and invoke with a post
    ibmcloud fn action get helloGo --url <- returns your url
    curl -X POST -d '{"name":"sfdsfs4 "}' https://us-south.functions.appdomain.cloud/api/v1/xxx/helloGo.json
  3. review the logs
    ibmcloud wsk activation logs --last # returns the logs
    notice that variable t0 is never reused. You always see "new t0" in the logs

Provide the expected results and outputs:

That it re uses the variables outside of main like for other runtimes. 

Provide the actual results and outputs:

It does not reuse variables outside of main. This is usually used to reuse db connection.

Additional information you deem important:

  • issue happens 100% of the time and should be easy to reproduce

Code for native / docker runtime
save as main.go
GOOS=linux GOARCH=amd64 go build -o exec
zip exec.zip exec
ibmcloud wsk action update helloGo --native exec.zip
ibmcloud fn action get helloGo --url <- returns your url
curl -X POST -d '{"name":"sfdsfs4 "}' https://us-south.functions.appdomain.cloud/api/v1//helloGo.json
ibmcloud wsk activation logs --last # returns the logs

package main

import (
    "fmt"
    "log"
    "os"
    "time"
    "encoding/json"
)
var t0 time.Time

func main() {
    log.Println("os.Args")
    log.Println(os.Args)

    if t0.IsZero() {
		t0 = time.Now()
		log.Println("new t0")
	} else {
		log.Println("re used t0")
    }

    msg := map[string]string{"body": ("Hello!")}
    res, _ := json.Marshal(msg)
    fmt.Println(string(res))
}
@jonee
Copy link
Author

jonee commented Jan 9, 2021

Or is this a known limitation of this runtime that uses binary?

@rabbah
Copy link
Member

rabbah commented Jan 11, 2021

The golang OpenWhisk runtime does reuse variables. You can try a properly working version here:
https://apigcp.nimbella.io/api/v1/web/playground/user463062/y

and see the code here:
https://apigcp.nimbella.io/api/v1/web/playground/default/showCode/user463062/y

@jonee
Copy link
Author

jonee commented Jan 11, 2021

I am aware that the golang runtime does reuse variables outside of main function.

But the native / docker does not. So probably if you use another programming language say Rust then compile statically then you could expect the same behaviour.

I would appreciate a confirmation that this is a limitation of the runtime and not a bug. Thanks!

@rabbah
Copy link
Member

rabbah commented Jan 11, 2021

Ah sorry - I missed the "native" qualification. In this model, each invocation is a new process, so there won't be any reuse. It's possible to implement an alternate protocol though but that involves using file descriptors (this is referred to as the action loop).

@rabbah
Copy link
Member

rabbah commented Jan 11, 2021

@jonee
Copy link
Author

jonee commented Jan 12, 2021

Thanks @rabbah !

When you have time can you please take a look at the other bug that I filed? #5043

@jonee jonee closed this as completed Jan 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants