/go-my-mutex

Mutex lock based on MySQL user-level locks for Go

Primary LanguageGoMIT LicenseMIT

go-my-mutex

Build Codecov ReportCard GoDoc License

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.

Install

$ go get -u -v github.com/vgarvardt/go-my-mutex

PostgreSQL drivers

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.

Usage example

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
}

How to run tests

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 ./...

MIT License

Copyright (c) 2019 Vladimir Garvardt