lock

package module
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 15, 2023 License: MIT Imports: 11 Imported by: 0

README

mysql-lock

golang-ci

a simple distributed lock based on mysql

Usage

go get github.com/vearne/mysql-lock

initialization

mlock.NewCounterLockWithDSN()
mlock.NewCounterLockWithConn()

Notice :Distributed locks based on mysql are not rigorous

For example, at t1, A holds the lock, and B waits for the lock. At t2, the network between A and MySQL is abnormal. MySQL actively releases the lock imposed by A.And B adds the lock. At this time, A will think that it owns the lock; B will also think that it holds the lock. The distributed lock actually fails.

Notice: mysql-lock will create the table.

  • mysql-lock creates the table _lock_counter.

So mysql-lock needs CREATE permission. Or you can use doc/schema.sql to create the table yourself.

Example

package main

import (
	"context"
	mlock "github.com/vearne/mysql-lock"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

const (
	DSN = "root:9E68-2607F7855D7D@tcp(127.0.0.1:23406)/testdb?charset=utf8&loc=Asia%2FShanghai&parseTime=true"
)

func main() {
	debug := false
	//debug := true

	locker := mlock.NewLockClientWithDSN(DSN, debug)

	// init() can be executed multiple times
	locker.Init()

	clientID := "client1"
	lockName := "lock1"
	lock, err := locker.NewLock(lockName,
		mlock.WithMaxLockTime(20*time.Second),
		mlock.WithClientID(clientID))
	if err != nil {
		log.Println("new lock", err)
		return
	}

	beginTime := time.Now()
	// wait until get lock
	err = lock.Acquire(context.Background())
	if err != nil {
		log.Println("can't acquire lock", "error", err)
		log.Println(time.Since(beginTime))
		return
	}

	log.Printf("%s got lock [%s]\n", clientID, lockName)
	time.Sleep(10 * time.Second)
	lock.Release(context.Background())
	log.Printf("%s release lock [%s]\n", clientID, lockName)

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT)
	<-ch
}

Documentation

Index

Constants

View Source
const (
	LockStatusOpen   = 0
	LockStatusClosed = 1
)

Variables

View Source
var (
	AcquireTimeoutErr error = errors.New("get lock timeout")
)

Functions

func InitMySQLWithConn added in v0.0.4

func InitMySQLWithConn(sqlDB *sql.DB, debug bool) *gorm.DB

initialize *gorm.DB with an existing database connection

func InitMySQLWithDSN added in v0.0.4

func InitMySQLWithDSN(dsn string, debug bool) *gorm.DB

initialize *gorm.DB with dsn

Types

type BackOff added in v0.0.8

type BackOff interface {
	NextBackOff() time.Duration

	// Reset to initial state.
	Reset()
}

BackOff is a backoff policy for retrying an operation.

type CallBackFunc added in v0.1.5

type CallBackFunc func(err error)

type ConstantBackOff added in v0.0.8

type ConstantBackOff struct {
	Interval time.Duration
}

func NewConstantBackOff added in v0.0.8

func NewConstantBackOff(d time.Duration) *ConstantBackOff

func (*ConstantBackOff) NextBackOff added in v0.0.8

func (b *ConstantBackOff) NextBackOff() time.Duration

func (*ConstantBackOff) Reset added in v0.0.8

func (b *ConstantBackOff) Reset()

type ExponentialBackOff added in v0.0.8

type ExponentialBackOff struct {
	InitialInterval time.Duration
	Multiplier      float64
	Counter         int
}

func NewExponentialBackOff added in v0.0.8

func NewExponentialBackOff(initInterval time.Duration, multiplier float64) *ExponentialBackOff

func (*ExponentialBackOff) NextBackOff added in v0.0.8

func (l *ExponentialBackOff) NextBackOff() time.Duration

func (*ExponentialBackOff) Reset added in v0.0.8

func (l *ExponentialBackOff) Reset()

type LinearBackOff added in v0.0.8

type LinearBackOff struct {
	InitialInterval time.Duration
	Counter         int
}

func NewLinearBackOff added in v0.0.8

func NewLinearBackOff(initInterval time.Duration) *LinearBackOff

func (*LinearBackOff) NextBackOff added in v0.0.8

func (l *LinearBackOff) NextBackOff() time.Duration

func (*LinearBackOff) Reset added in v0.0.8

func (l *LinearBackOff) Reset()

type LockClient added in v0.1.5

type LockClient struct {
	MySQLClient *gorm.DB
}

func NewLockClientWithConn added in v0.1.5

func NewLockClientWithConn(db *sql.DB, debug bool) *LockClient

func NewLockClientWithDSN added in v0.1.5

func NewLockClientWithDSN(dsn string, debug bool) *LockClient

func (*LockClient) Init added in v0.1.5

func (client *LockClient) Init()

Init :Create tables

func (*LockClient) NewLock added in v0.1.5

func (client *LockClient) NewLock(lockName string, opts ...Option) (*MySQLLock, error)

type LockCounter added in v0.0.4

type LockCounter struct {
	Name       string    `gorm:"column:name;size:100;index:uni_name,unique" json:"name"`
	Owner      string    `gorm:"column:owner;size:100" json:"owner"`
	Counter    uint64    `gorm:"column:counter" json:"counter"`
	CreatedAt  time.Time `gorm:"column:created_at;type:datetime NOT NULL;default:CURRENT_TIMESTAMP" json:"createdAt"`
	ModifiedAt time.Time `gorm:"column:modified_at;type:datetime NOT NULL;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" json:"modifiedAt"`
	ExpiredAt  time.Time `gorm:"column:expired_at" json:"expiredAt"`
	// other
	ID int `gorm:"column:id" json:"id"`
}

func (LockCounter) TableName added in v0.0.4

func (LockCounter) TableName() string

type LockItf added in v0.1.5

type LockItf interface {
	Acquire(ctx context.Context) error
	Release(ctx context.Context) error
}

type MySQLLock

type MySQLLock struct {
	// contains filtered or unexported fields
}

func (*MySQLLock) Acquire

func (l *MySQLLock) Acquire(ctx context.Context) error

func (*MySQLLock) Refresh added in v0.1.5

func (l *MySQLLock) Refresh() error

func (*MySQLLock) Release

func (l *MySQLLock) Release(ctx context.Context) error

type MySQLLockItf added in v0.0.4

type MySQLLockItf interface {
	Init(lockNameList []string)
	Acquire(lockName string, wait time.Duration) error
	Release(lockName string) error
}

type Option added in v0.1.5

type Option func(lock *MySQLLock)

func WithBackOff added in v0.1.5

func WithBackOff(b BackOff) Option

func WithCallBack added in v0.1.5

func WithCallBack(f CallBackFunc) Option

If an error occurs when performing refresh, execute this callback

func WithClientID added in v0.1.5

func WithClientID(clientID string) Option

func WithMaxLockTime added in v0.1.5

func WithMaxLockTime(d time.Duration) Option

func WithRefreshBG added in v0.1.5

func WithRefreshBG(refreshBG bool) Option

Directories

Path Synopsis
example
client1 command
client2 command
election command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL