snowflakedb / gosnowflake

Go Snowflake Driver
Apache License 2.0
301 stars 125 forks source link

Expose `CLIENT_SESSION_KEEP_ALIVE` as a configuration option similarly to other drivers #847

Open segfault16 opened 1 year ago

segfault16 commented 1 year ago

Please answer these questions before submitting your issue. In order to accurately debug the issue this information is required. Thanks!

  1. What version of GO driver are you using?

v1.6.22

  1. What operating system and processor architecture are you using?

linux amd64

  1. What version of GO are you using?

1.20.4

5.Server version:* E.g. 1.90.1

  1. What did you do?

Backend service returns 390114: Authentication token has expired. The user must authenticate again after some time after being started. The service uses private key authentication with snowflake db and is intended to serve an API to a webapp. So it's long-running. I've read about the heartbeat functionality, but it doesn't seem to prevent this error.

  1. What did you expect to see?

  2. Can you set logging to DEBUG and collect the logs?

    https://community.snowflake.com/s/article/How-to-generate-log-file-on-Snowflake-connectors

  3. What is your Snowflake account identifier, if any? (Optional)

sfc-gh-dszmolka commented 1 year ago

hello and thank you for submitting this issue ! also great that you already read upon the keep alive functionality; it is indeed the way to go to refresh the authentication token which by default has a 4-hour lifetime - to refresh it, you need to send keepalives with the driver (or alternatively, any dummy query like SELECT 1 every now and then)

the keepalives are enabled and automatically sent every hour when the parameter CLIENT_SESSION_KEEP_ALIVE is set in the connection parameters per the driver documentation.

you can find a full connection string example at the above documentation section, or if you look into the driver_test.go file, the createDSNWithClientSessionKeepAlive function also has an example how to set this parameter.

hope this helps - if it doesn't, please send a minimal viable reproduction program which when run, exhibits the behaviour of the driver not sending keepalives.

segfault16 commented 1 year ago

Hi, testing now with

    t := "true"
    cfg := &sf.Config{
        Account:       sfAccount,
        User:          sfUser,
        Database:      sfDatabase,
        Schema:        sfSchema,
        Warehouse:     sfWarehouse,
        Role:          sfRole,
        Authenticator: sf.AuthTypeJwt,
        PrivateKey:    rsaPrivateKey,
        Params:        map[string]*string{"client_session_keep_alive": &t},
    }

which to be honest looks pretty ugly and is not that obvious when reading the documentation. Also by the time this error occurred I could've already deployed to production. I'd expect a DB package to behave differently here.

segfault16 commented 1 year ago

Confirmed working for > 24 hours now.

How about having this as a separate config option (I hope you agree the Params above is pretty ugly), having this turned on as a default or maybe even providing the config as a func() *sf.Config argument to sf.DSN() to mitigate SF driver having credentials in memory during runtime but still providing a similar experience like other db drivers and being able to open new connections with proper error handling?

sfc-gh-dszmolka commented 1 year ago

okay, that's good to hear the parameter works as intended so now you have a way to keep the long running connection alive. exposing it as a nice configuration setting also makes sense, and we'll look into that. I'm editing the Issue summary to reflect it.

segfault16 commented 10 months ago

@sfc-gh-anugupta any updates? ETA?

sfc-gh-dszmolka commented 10 months ago

no timeline estimates as of now, but will share if any new information becomes available (functionality works as of today, request is to expose it in a different way similarly to other drivers)