Mutex lock based on MySQL user-level locks for Go. Can be used to acquire a lock on a resource exclusively across several running instances of the application.
$ go get -u -v github.com/vgarvardt/go-my-mutex
The store accepts an adapter interface that interacts with the DB. Adapter and implementations are extracted to separate package github.com/vgarvardt/go-pg-adapter
for easier maintenance.
package main
import (
"context"
"fmt"
"os"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/vgarvardt/go-my-mutex"
"github.com/vgarvardt/go-pg-adapter/sqladapter"
)
func main() {
db, _ := sql.Open("mysql", os.Getenv("DB_URI"))
defer db.Close()
conn, _ := db.Conn(context.Background())
defer conn.Close()
m, _ := mymutex.New(sqladapter.NewConn(conn))
useExclusiveResource(m)
if !useExclusiveResourceOrNoOp(m) {
fmt.Println("Resource is busy, doing nothing")
}
}
func useExclusiveResource(m *pgmutex.PgMutex) {
lockName := "my-lock"
_ := m.Lock(lockName)
defer m.Unlock(lockName)
// do something with resource exclusively across several instances
}
func useExclusiveResourceOrNoOp(m *pgmutex.PgMutex) bool {
lockName := "my-try-lock"
if success, _ := m.TryLock(lockName); !success {
return false
}
defer m.Unlock(lockName)
// do something with resource exclusively across several instances
}
You will need running MySQL instance. E.g. the one running in docker and exposing a port to a host system
docker run --rm -p 3306:3306 -it -e MYSQL_ROOT_PASSWORD=mutex -e MYSQL_DATABASE=mutex mysql:5.7
Now you can run tests using the running PostgreSQL instance using MY_URI
environment variable
MY_URI="root:mutex@tcp(localhost:3306)/mutex" go test -cover ./...
Copyright (c) 2019 Vladimir Garvardt