0

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()
thomas
  • 71
  • 6
  • In serverless frameworks like IBM Cloud Functions, every function / action is run on its own. You can try passing the connection info as a parameter between actions – data_henrik Apr 20 '20 at 10:07
  • @data_henrik actually other serverless providers like AWS lambda allow database connections to be reused to save computation time, but thanks. – thomas Apr 20 '20 at 10:09
  • There are code samples that make use of the same concepts, relying on the container to be reused. https://thecodebarbarian.com/getting-started-with-ibm-cloud-functions-and-mongodb.html Personally, I prefer a clean approach – data_henrik Apr 20 '20 at 10:48
  • @data_henrik this is the solution I initially mentioned in my post and it does not work – thomas Apr 20 '20 at 11:03

1 Answers1

1

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.

user6062970
  • 831
  • 4
  • 5