-3

In one package, i declare some variable and also a mutex variable. I want to use it to lock or unlock get/set of package level variables.

var mutex sync.Mutex
var tplPath = ""

func Prepare(c *gin.Context) {
    mutex.Lock()
    tplPath = "abc"
    mutex.Unlock()
}

Can it be consider as good practice while using mutex can prevent race condition of get/set on tplPath in concurrency http request?

TomSawyer
  • 3,711
  • 6
  • 44
  • 79
  • This usage looks fine, but you shouldn't use a single mutex to protect all global variables, as you may unnecessary block goroutines attempting to access only other variables. Also see related: [When do you embed mutex in struct in Go?](https://stackoverflow.com/questions/44949467/when-do-you-embed-mutex-in-struct-in-go/44950096#44950096) – icza Jun 15 '18 at 09:47
  • Good practice is very vague. – Volker Jun 15 '18 at 09:50

1 Answers1

0

Using package level variables is not always good or always bad. Depending on problem.

The only thing about this specific code example, is that you could possibly end up in a state where you are locking and unlocking in multiple places in code.

If you choose to go down this route; which is fine, consider extracting the tplPath and mutex into a type.

// create type and expose values through getters and setters 
// to ensure the mutex logic is encapsulated.
type path struct {
    mu sync.Mutex
    val string
}

func (p *path) setPath(path string) {
    p.mu.Lock()
    defer p.mu.Unlock()
    p.val = path
}

func (p *path) path() string {
    p.mu.Lock()
    defer p.mu.Unlock()
    return p.val
}

var tplPath *path

func init() {
    // use package init to make sure path is always instantiated
    tplPath = new(path)
}

func Prepare(c *gin.Context) {
    tplPath.setPath("abc")
}
Zak
  • 5,515
  • 21
  • 33