mvhatch
mvhatch

Reputation: 157

golang singletons in beego

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

Answers (3)

Shady Keshk
Shady Keshk

Reputation: 570

Here is everything you need to know about creating singleton in Golang

Singleton Pattern in Go

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

mvhatch
mvhatch

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

fabmilo
fabmilo

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

Related Questions