Reputation: 157
I'm trying out both Golang and Beego. I come from a Java/Spring background and I'm having a slightly difficult time implementing a singleton pattern for a webapp I'm developing. I have a controller (which I want to be a singleton) and I have a service within my controller (which I also want to be a singleton). I thought if I made my service a pointer, then I'd always use the same address (a singleton). This is not proving true.
My route looks like this
beego.Router("/", &controllers.SessionController{}, "get:Login")
My SessionController looks like this
type SessionController struct {
baseController
userService *services.UserService
}
func (this *SessionController) Prepare() {
this.baseController.Prepare()
if this.userService == nil {
beego.Info("user service was nil")
this.userService = factories.NewUserService()
}
}
My logs always show that the user service is nil upon each request. How can I get a single instance of my controller with a single (initialized only once) instance of my user service?
Upvotes: 1
Views: 1069
Reputation: 570
Here is everything you need to know about creating singleton in Golang
var instance *singleton
func GetInstance() *singleton {
if instance == nil {
instance = &singleton{} // <--- NOT THREAD SAFE
}
return instance
}
But that is not THREAD SAFE , you will need to use the Sync once Example :-
import (
"sync"
)
type singleton struct {
}
var instance *singleton
var once sync.Once
func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
Upvotes: 0
Reputation: 157
1 of the creators of the Beego framework has mentioned to me that the framework creates a new instance of a controller per request, so it's not really possible to create a singleton :(
Upvotes: 2
Reputation: 48330
Make the user Service a singleton:
var globalUserService = factories.NewUserService()
type SessionController struct {
baseController
userService *services.UserService
}
func (this *SessionController) Prepare() {
this.baseController.Prepare()
if this.userService == nil {
beego.Info("user service was nil")
this.userService = globalUserService
}
}
Upvotes: 2