Skip to content
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

Time out when using VPC Serverless Access in Cloud Function #297

Open
dnnane opened this issue Apr 11, 2024 · 1 comment
Open

Time out when using VPC Serverless Access in Cloud Function #297

dnnane opened this issue Apr 11, 2024 · 1 comment
Assignees
Labels
priority: p2 Moderately-important priority. Fix may not be included in next release. type: question Request for information or clarification.

Comments

@dnnane
Copy link

dnnane commented Apr 11, 2024

Bug Description

I cannot get this connector working in a cloud function, i get a time out error.

I am following steps outlined in this codelab using a connection through a VPC Serverless Access to an AlloyDB instance in a cluster.

I tried the plain codelab, it is working.

When using your connector in a Cloud Function, I am unable to connect (time out).

My code in the cloud function is as follow:

Do you have more insights ? I think that error messages shall be more clear, time out means almost nothing.

Example code (or command)

from google.cloud.alloydb.connector import Connector

# initialize Connector object
connector = Connector()

# function to return the database connection
def getconn():
    conn = connector.connect(
        "projects/<YOUR_PROJECT>/locations/<YOUR_REGION>/clusters/<YOUR_CLUSTER>/instances/<YOUR_INSTANCE>",
        "pg8000",
        user="postgres",
        password="postgres",
        db="postgres"
    )
    return conn

def action(request):
   print(getconn())


### Stacktrace

```bash
`Function execution took 58500 ms, finished with status: 'timeout'`

Steps to reproduce?

  1. Follow codelab entirely
  2. Create a Cloud function (with the VPC connector) with code specified above
  3. Test the Cloud function

Environment

  1. OS type and version: Mac OS Sonoma 14.4.1
  2. Python version: 3.12
  3. AlloyDB Python Connector version: 1.0.0

Additional Details

No response

@dnnane dnnane added the type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. label Apr 11, 2024
@jackwotherspoon
Copy link
Collaborator

Hi @dnnane! Thanks for raising an issue on the AlloyDB Python Connector 😄

What you are experiencing is most likely the equivalent of GoogleCloudPlatform/cloud-sql-python-connector#830 (comment)

The Python Connector schedules background tasks to call AlloyDB APIs to get a valid certificate for the SSL connection as well as to retrieve metadata such as the IP address to connect to.

If you initialize the Connector as a regular global variable it will timeout because Cloud Functions only allocates CPU at the time of the first request, during the request context (aka when the action function is called). This is why Cloud Functions recommends lazy initializing global variables.

You could try something along the lines of:

from google.cloud.alloydb.connector import Connector

# lazy init Connector
connector = None

# function to return the database connection
def getconn():
    conn = connector.connect(
        "projects/<YOUR_PROJECT>/locations/<YOUR_REGION>/clusters/<YOUR_CLUSTER>/instances/<YOUR_INSTANCE>",
        "pg8000",
        user="postgres",
        password="postgres",
        db="postgres"
    )
    return conn

def action(request):
   if connector is None:
       connector = Connector()
   print(getconn())

Even using the Connector as a lazy global variable may lead to some issues if Cloud Functions scales down to zero as again the background refreshes of the Python Connector may be throttled. This is currently a known issue and I created #298 to track adding a lazy refresh option where you can configure the Connector to not schedule background refreshes.

Since you are using Private IP connection you may be interested in not using the Python Connector and instead connecting directly to your instance using its Private IP address until the limitations are fixed.

Example would be using psycopg2:

import psycopg2

def action(request):
  # see https://www.psycopg.org/docs/usage.html for usage
  conn = psycopg2.connect(
    dbname="test", 
    user="postgres", 
    password="secret", 
    host="<YOUR-ALLOYDB-PRIVATE-IP>", 
    port=5432
  )
  # Open a cursor to perform database operations
  cur = conn.cursor() 
  # perform a query
  cur.execute("SELECT NOW()")

@jackwotherspoon jackwotherspoon added priority: p2 Moderately-important priority. Fix may not be included in next release. type: question Request for information or clarification. and removed type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Apr 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p2 Moderately-important priority. Fix may not be included in next release. type: question Request for information or clarification.
Projects
None yet
Development

No branches or pull requests

2 participants