*DEPRECATED* Please use https://gopkg.in/redsync.v1 (https://github.com/go-redsync/redsync)

Redsync.go

This package is being replaced with https://gopkg.in/redsync.v1. I will continue to maintain this package for a while so that its users do not feel abandoned. But I request everyone to gradually switch to the other package which will be maintained more actively.

Build Status

Redsync.go provides a Redis-based distributed mutual exclusion lock implementation for Go as described in this blog post. A reference library (by antirez) for Ruby is available at github.com/antirez/redlock-rb.

Installation

Install Redsync.go using the go get command:

$ go get github.com/hjr265/redsync.go/redsync

The only dependencies are the Go distribution and github.com/garyburd/redigo/redis.

Documentation

Contributing

Contributions are welcome.

License

Redsync.go is available under the BSD (3-Clause) License.

Disclaimer

This code implements an algorithm which is currently a proposal, it was not formally analyzed. Make sure to understand how it works before using it in production environments.

Owner
Mahmud Ridwan
Muslim.
Mahmud Ridwan
Comments
  • Separate connection pooling from mutex handling (fixes #10)

    Separate connection pooling from mutex handling (fixes #10)

    I've introduced a new API as discussed in #10. There is a problem though, the tests always fail for me, with or without this PR. I'm running it with go test ./redsync/mutext_test.go and it fails with:

    --- FAIL: TestMutex (24.60s)
            mutex_test.go:84: failed to acquire lock
    FAIL
    FAIL    command-line-arguments  24.670s
    

    I'm not sure why this is happenning. Any ideas?

  • Separate connection pooling from mutex {un,}locking

    Separate connection pooling from mutex {un,}locking

    The godoc example (and all other New* functions) require passing Redis credentials/connections everytime when acquiring a mutex.

    Instead of that, an API that separates connections from mutexes seems much more usable. For example:

    // redsync.New returns *RedSync
    redsync := redsync.New([]net.Addr{
        &net.TCPAddr{Port: 6379},
        &net.TCPAddr{Port: 6380},
    })
    
    lock, err := redsync.Lock("foo")
    if err != nil {
        // success!
    }
    
    redsync.Unlock(lock)
    

    This way, a single RedSync instance could be shared across the codebase without dealing with connection parameters everywhere. What do you think?

  • Redsync for a shared resource across a distributed system

    Redsync for a shared resource across a distributed system

    Dear Authors,

    Thanks for your effort in implementing the redsync algorithm in go. I am trying to use your implementation in a distributed system where multiple nodes might request for the same named resource. In that case, though the mutexes created for the same named resource are different, the lock should still succeed for one and only one node.

    The delScript inside Lock() prevents this from happening. I am trying to understand why you would need that in the first place?

    ( I'd like to simulate the following behaviour at the redis-server:

    127.0.0.1:6379> get uuid1 (nil) 127.0.0.1:6379> set uuid1 2345 NX PX 200000 OK 127.0.0.1:6379> get uuid1 "2345" 127.0.0.1:6379> set uuid1 1234 NX PX 200000 (nil) 127.0.0.1:6379> get uuid1 "2345"

    A get fetching a non-nil value should suffice, the value needn't be equal )

    Thanks, Smita

  • Is  `Touch() bool` really needed?

    Is `Touch() bool` really needed?

    Why caller should call Touch() ? What if Touch() is hidden by Lock()

    In Lock(): run a goruntine to call Touch() regularly. Then caller can only focus on Lock() and Unlock()

  • This is an incomplete implementation of Redlock.

    This is an incomplete implementation of Redlock.

    There's no quorum code and the initialization assumes that you can successfully connect to all the Redis servers, some of which may be unavailable.

    The Ruby implementation seems to be a bit more complete.

    Any plan to fix these?

  • Simple example fails with

    Simple example fails with "failed to acquire lock"

    This simple example fails with "failed to acquire lock"

    I am using go tip: go version devel +811b785 Wed Feb 10 14:42:30 2016 +0000 linux/amd64 package main

    import ( "log" "net"

    "github.com/hjr265/redsync.go/redsync"
    

    )

    func main() { m, err := redsync.NewMutex("foo", []net.Addr{&net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 6379}}) if err != nil { log.Fatal(err) } err = m.Lock() if err != nil { log.Fatal(err) } m.Unlock()

    }

  • Proposed fix for Issue#8

    Proposed fix for Issue#8

    The following changes have been introduced to the library in this pull request:

    1. Adding touch function to redsync Locker interface: Touch() function resets the expiry of a valid (key,value) on the Redis cluster. It does this using the touchScript. Touch script assumes a valid (key,value) pair which is valid at the time "GET" is invoked at the particular node in the Redis cluster. If found, the timer value is reset to original slice. Else, the (key,value) is not created. Touch() returns the status of touch, and therefore, the validity of the mutex of the caller. The function returns true if expiry at atleast Quorum number of nodes was successfully reset. This means the lock is valid at atleast Quorum nodes, and therefore is valid and held by the caller. Else, the caller does not have a valid mutex (possibly timed out).
    2. Changing Unlock() to return status of unlock of a mutex: Similar to the touch function, the Unlock() function's signature has been changed to return the status of Unlock(). If Unlock() successfully found and deleted the (key,value) at atleast Quorum number of nodes, then Unlock() was successful on a valid mutex. Else, the mutex was invalid (possibly had timed out), therefore, Unlock() was unsuccessful.
  • repo name redsync.go illegal by latest Godep

    repo name redsync.go illegal by latest Godep

    It turns out the latest Godep https://github.com/tools/godep/ does not allow for imported repos to be of the form *.go, meaning redsync.go breaks it. Would be good to copy the repo into a different one with a supported Godep name. The name of the newer package under development https://github.com/redsync/redsync/ seems fine so I look forward to that being available!

  • Use EVALSHA, allow redis authentication and reuse connections

    Use EVALSHA, allow redis authentication and reuse connections

    This PR includes:

    • [x] Refactoring to make code pass glint
    • [x] Change library from radix to redigo, which includes using EVALSHA (fixes #2)
    • [x] Use tempredis to automatically start redis servers for testing
    • [x] Add NewMutexWithPool so redigo's Pool of hosts can be used, allowing reusing existing redis connections.
    • [x] Allow redis authentication using redis.Pool Dial. See redis.Pool example

    @hjr265 let me know what you think.

  • why the Lock and Unlock method need

    why the Lock and Unlock method need "m.nodem.Lock"?

    Hi hjr265,

    as I have known, the redis set operation with "NX" will promise distributed lock, reply, err := redis.String(conn.Do("SET", m.name, value, "NX", "PX", int(m.expiry/time.Millisecond)))

    so it confused me, why the Lock and Unlock method need m.nodem.Lock? and will the m.nodem.Lock lead to deadlock?

    func (m *Mutex) Lock() error {
    	m.nodem.Lock()
    	defer m.nodem.Unlock()
            ...
    }
    
  • Connection Pool parameters need to be configurable

    Connection Pool parameters need to be configurable

    Hi Mahmud, Since connection pool parameters are configurable in the redigo library [https://github.com/garyburd/redigo/blob/master/redis/pool.go], isn't it then better to take these also as a parameter when creating a new mutex?

    In my particular case, I hit a problem with the MaxActive pool value set to 1. Running a load of 1000+ requests per parameter, the average wait time for a Lock() to return successfully was about 9.8 seconds. I ran it with (an extreme) MaxActive = 0, and the value came down to 6.6ms!

    IMO, application should allow parallel unrelated requests to go through and related requests should be synchronized. The library should take this input and work with it. Defaults may be used (like the constants defined currently) in the absence of application-defined values.

    What do you think? May I go ahead release a pull request for the same?

  • Unlocking from separate process?

    Unlocking from separate process?

    Call me crazy but if this is for distributed locking, then why is it impossible to unlock from another process?

    https://github.com/hjr265/redsync.go/blob/master/redsync/mutex.go#L281-L284

    If i'm calling Lock() from one daemon, the key gets added to redis as you'd expect. I call Unlock() in another daemon with the same named mutex, pool, etc, this is impossible because 'value' will obviously not be set. Am I missing something, is it not supposed to be used this way?

Go Library [DEPRECATED]

Tideland Go Library Description The Tideland Go Library contains a larger set of useful Google Go packages for different purposes. ATTENTION: The cell

Nov 15, 2022
Distributed lock manager. Warning: very hard to use it properly. Not because it's broken, but because distributed systems are hard. If in doubt, do not use this.

What Dlock is a distributed lock manager [1]. It is designed after flock utility but for multiple machines. When client disconnects, all his locks are

Dec 24, 2019
Dkron - Distributed, fault tolerant job scheduling system https://dkron.io
Dkron - Distributed, fault tolerant job scheduling system https://dkron.io

Dkron - Distributed, fault tolerant job scheduling system for cloud native environments Website: http://dkron.io/ Dkron is a distributed cron service,

Dec 28, 2022
dht is used by anacrolix/torrent, and is intended for use as a library in other projects both torrent related and otherwise

dht Installation Install the library package with go get github.com/anacrolix/dht, or the provided cmds with go get github.com/anacrolix/dht/cmd/....

Dec 28, 2022
Easy to use Raft library to make your app distributed, highly available and fault-tolerant
Easy to use Raft library to make your app distributed, highly available and fault-tolerant

An easy to use customizable library to make your Go application Distributed, Highly available, Fault Tolerant etc... using Hashicorp's Raft library wh

Nov 16, 2022
Native ZooKeeper client for Go. This project is no longer maintained. Please use https://github.com/go-zookeeper/zk instead.

Native Go Zookeeper Client Library License 3-clause BSD. See LICENSE file. This Repository is No Longer Maintained Please use https://github.com/go-zo

Dec 19, 2022
Library to integrate github.com/google/uuid with gopkg.in/vmihailenco/msgpack

Library to integrate github.com/google/uuid with gopkg.in/vmihailenco/msgpack

Apr 26, 2022
:exclamation::exclamation::exclamation: [deprecated] Moved to https://github.com/go-macaron/macaron
:exclamation::exclamation::exclamation: [deprecated] Moved to https://github.com/go-macaron/macaron

Macaron Package macaron is a high productive and modular web framework in Go. Current version: 0.6.8 Getting Started The minimum requirement of Go is

Aug 20, 2021
:exclamation::exclamation::exclamation: [deprecated] Moved to https://github.com/go-macaron/macaron
:exclamation::exclamation::exclamation: [deprecated] Moved to https://github.com/go-macaron/macaron

Macaron Package macaron is a high productive and modular web framework in Go. Current version: 0.6.8 Getting Started The minimum requirement of Go is

Aug 20, 2021
gopkg is a universal utility collection for Go, it complements offerings such as Boost, Better std, Cloud tools.

gopkg is a universal utility collection for Go, it complements offerings such as Boost, Better std, Cloud tools. Table of Contents Introduction

Jan 5, 2023
Gopkg - Search go.dev packages by keyword

gopkg Search go.dev packages by keyword Usage Install go install github.com/luck

Apr 6, 2022
Geometry/geography library in Go, DEPRECATED, use ->

go.geo (deprecated) Go.geo is a geometry/geography library in Go. The primary use case is GIS geometry manipulation on the server side vs. in the brow

Jan 2, 2023
This is old and unmaintained code, ignore it. starfish is a simple, SDL based, 2D graphics and user input library for Go. If you intend to work on it, please fork from the 'devel' branch, not 'master'. Current release: 0.12.0

What is starfish? What starfish is: starfish is a simple 2D graphics and user input library for Go built on SDL. What starfish is not: While it is bui

Jun 4, 2019
Hard fork of jteeuwen/go-bindata because it disappeared, Please refer to issues#5 for details.

Warning this repository is not maintained. Questions or suggestions can be posted here. bindata This package converts any file into managable Go sourc

Jan 7, 2023
Please is a cross-language high-performance extensible build system for reproducible multi-language builds.

Please is a cross-language build system with an emphasis on high performance, extensibility and reproducibility. It supports a number of popular languages and can automate nearly any aspect of your build process.

Dec 30, 2022
This is an example of a keep-it-simple directory layout for Go projects that was created using DDD principles, please copy and share if you like it.

DDD Go Template This project was created to illustrate a great architectural structure I developed together with @fabiorodrigues in the period I was w

Dec 5, 2022
I will be uploading some basic programming in Golang so if you want to contribute please Fork this repo and contriute.
I will be uploading some basic programming in Golang so if you want to contribute please Fork this repo and contriute.

Go-language I will be uploading some basic programming in Golang so if you want to contribute please Fork this repo and contriute. This repo is for pr

Jan 21, 2022
Discord token grabber written in go please read the liability disclaimer before using it
Discord token grabber written in go please read the liability disclaimer before using it

Discord Token Grabber Written in Go ! Liability Disclaimer ⚠ The use of this sof

Jan 1, 2023
Package githubv4 is a client library for accessing GitHub GraphQL API v4 (https://developer.github.com/v4/).

githubv4 Package githubv4 is a client library for accessing GitHub GraphQL API v4 (https://docs.github.com/en/graphql). If you're looking for a client

Dec 26, 2022