I’m working on integrating PostgreSQL into my Go project and have a few questions about structuring the psqlClient:
Initialization Strategy: Should I initialize the psqlClient at the start of the application and maintain a single instance throughout? If so, how do I ensure it’s globally accessible? But then opens up to posibility so many problems.
func main(){
// global instance
// problem: race conditions, and how to access from different services
psqlClient = psql_client.NewPsqlClient()
}
Service Initialization: Alternatively, is it better to initialize the psqlClient at the time of service initialization? My concern here is that multiple project-level services (like role_service.go and action_service.go) might each need their own client, leading to potential duplication of connection pools and other resources.
---- psql_client.go ----
type PsqlClient{
client *db.SQL // or something like this
}
func NewPsqlClient() PsqlClient{
// initialize new psql client on each call
return psqlClient
}
--- user_service.go ----
func NewUserService(){
psqlClient = psql_client.NewPsqlClient() // psql client duplicated across service
}
---- action_service.go ----
func NewActionService(){
psqlClient = psql_client.NewPsqlClient() // psql client duplicated across service
}
Using sync.Once for Singleton Initialization: I’ve considered using sync.Once to ensure only a single instance of psqlClient is created. However, I foresee a challenge: what if different services require initialization of psqlClient with different databases?
psql_client.go
var psqlClient psqlClient
var psqlClientOnce sync.Once
func NewPsqlClient() {
psqlClientOnce.do(
// logic to initialize psqlClient
psqlClient = initializedClient
)
}
Could anyone share insights or best practices on how to effectively manage psqlClient within a Go application? Also, by “service” I mean project-level services such as role_service.go and action_service.go. Thanks in advance for your help!