Search posts, tags, users, and pages
Is it just me or does sync.Once compound the problem? While &sql.Open(...) is running, all other DBConnection will return nil?
The idea here is that you only need to open a database connection once. According to go docs, the Open() function returns a connection that is "safe for concurrent use by multiple goroutines and maintains its own pool of idle connections. Thus, the Open function should be called just once. It is rarely necessary to close a DB."
So you can call on the init function on start (there will be no other calls to it at this point) and that's it. You can refer to the docs here: golang.org/pkg/database/sql
Sayed Alesawy As far as I understand, in this case sql.Open is just for example, which means there could be any other function with indefinite execution time.
I would like to return to the problem stated in paragraph 2 (without init function): ...Consider the case where 2 goroutines are calling the function DBConnection() at the same time. It's possible that the first goroutine reads the value of dbInstance and finds it nil and then proceeds to create a new connection...
Does dbOnce.Do block the rest of the function's calls for the execution time, or just let them pass by and return nil?
Oleksiy Oh, I understand what you mean now. That's a really nice case to think about.
As far as I know, calls to sync.Once won't return until the function f() inside the Do function returns. So if multiple goroutines call it concurrently, they will block waiting until the first call returns, then they will be executed, but of course they won't re-execute Once again.
I wrote this code: play.golang.org/p/ftvpEyhHDio to make sure and try it out. You can try changing the value of Sleep at line 22 to something bigger and you will see that the routines are blocked.
Considering this behavior, I still think it's good for initializations.
Sayed Alesawy Ah, great, then the question is off the table. Yes, I've now studied the Once.Do implementation, it's fun and seems to be specifically designed to lock other calls until the return from the function happens.