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

added code for setting and getting session variable in postgres #673

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

alkuma
Copy link

@alkuma alkuma commented Dec 18, 2023

This is raised as an issue at go-gorm/gorm#6753 and this is the underlying code example

Explain your user case and expected results

We are implementing session variables in postgresql to take advantage of row level security (RLS) in postgresql.

For this purpose, we need

  1. request 1 - has the session variable value set to TENANT1
  2. request 2 - has the session variable set to TENANT2

Both requests can be concurrent.

So we require that after opening the connection using gorm.Open(), it should be possible to obtain two separate connections from the underlying connection pool and both should work independent of each other such that one has session variable value set to TENANT1 and the other has session variable set to TENANT2

However, we note by running

GORM_DIALECT=postgres go test

that the output is

2023/12/18 12:26:51 testing postgres...
FATA-010 DB Ptr is [0xc0003b1410]
FATA-020 & DB Ptr is [0x125a140]

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/db.go:147
[0.081ms] [rows:0] SET myapp.current_tenant_id = 'TENANT1'
FATA-030 DB session 1 is [0xc0004e8000]
FATA-040 &DB session 1 is [0xc0004bc240]

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/db.go:124
[0.155ms] [rows:1] SELECT current_setting('myapp.current_tenant_id')
FATA-050 dbPtr1 tenantId is [TENANT1]

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/db.go:128
[0.061ms] [rows:1] SELECT current_setting('myapp.current_tenant_id')
FATA-060 from1Session1 tenantId is [TENANT1]

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/db.go:147
[0.054ms] [rows:0] SET myapp.current_tenant_id = 'TENANT2'
FATA-070 DB session 2 is [0xc0004e8270]
FATA-080 &DB session 2 is [0xc0004bc278]

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/db.go:136
[0.057ms] [rows:1] SELECT current_setting('myapp.current_tenant_id')
FATA-120 from1Session1 tenantId is [TENANT2]

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/db.go:140
[0.058ms] [rows:1] SELECT current_setting('myapp.current_tenant_id')
FATA-130 from1Session2 tenantId is [TENANT2]

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/main_test.go:14
[0.832ms] [rows:1] INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2023-12-18 12:26:51.536','2023-12-18 12:26:51.536',NULL,'jinzhu',0,NULL,NULL,NULL,false) RETURNING "id"

2023/12/18 12:26:51 /home/alok/github.com/alkuma/gorm-connection-pool/main_test.go:17
[0.359ms] [rows:1] SELECT * FROM "users" WHERE "users"."id" = 1 AND "users"."deleted_at" IS NULL ORDER BY "users"."id" LIMIT 1
PASS
ok  	gorm.io/playground	0.047s

As can be seen, FATA-050 and FATA-060 have the value set to TENANT1

However, the moment we set the value for the second session to TENANT2, the value is updated for both the first session as well as the second session, which means they are both one and the same.

So the question is? How do we obtain two distinct sessions / connections (or whatever is the terminology gorm uses) that can perform operations in parallel?

A very simple solution is to just create a new database connection using the dsn and gorm.Open() every time, but then there is no connection pooling - is our understanding.

The other solutions seems to be to create a new connection whenever a new tenant is encountered and return the correct *gorm.DB based on the tenant Id. This means that the number of connection pools will be equal to the number of tenants - that's a better solution than the first one but we are still not able to use connections from the same pool for multiple tenant requests.

So how do we do this in an efficient manner?

This is raised as an issue at go-gorm/gorm#6753 and this is the underlying code example

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

Successfully merging this pull request may close these issues.

1 participant