goibm-cloudserverlessopenwhiskibm-cloud-functions

How can one reuse a database connection in Golang Cloud functions?


I am currently trying to migrate my application to IBM cloud functions, but one issue that I am facing is keeping the Postgresql DB from beeing reconnected every time an action is invoked.

I have found very little information about how to reuse a DB connection in Go, and the solutions I have tried (keeping the database handler in a global variable) does not work.

Would anyone be able to point me to the right doc?

Thanks,

-Thomas

PS: Here is a snippet of code that illustrates the way I tried:

func Storage() Storager {
    once.Do(func() {
        db := InitDB()
        println("Initiating DB...")
        s = &storage{
            db: db,
        }
    })

    return s
}

// This is declared as a global variable in main
var s = storage.Storage()

Solution

  • It is possible to retain global state inside an OpenWhisk actions and this works for Golang functions. For example here's a counter.go function which increments a global counter for every invocation of the function.

    package main
    
    var counter = 1
    
    func Main(args map[string]interface{}) map[string]interface{} {
      msg := make(map[string]interface{})
      msg["counter"] = counter
      counter = counter + 1
      return msg
    }
    

    If you create this action and run it multiple times in succession, you will see the counter value is increased each time.

    > wsk action create counter counter.go
    > wsk action invoke counter --result
    {
      "counter": 1
    }
    > wsk action invoke counter --result
    {
      "counter": 2
    }
    > wsk action invoke counter --result
    {
      "counter": 3
    }
    

    So what you are trying to do should work. In your example, check that the action is completing successfully and not raising an error and failing (which prevents further reuse). Additionally, check the activation record to see if the activation was warm or cold. This can be seen by checking if the activation record has an initTime annotation to indicate cold starts. If not present the activation is warm and the newest activation ran in the same context as some previous activation.