How do I use distributed locks with Redis in Go?

Using distributed locks with Redis in Go can help synchronize access to shared resources across multiple instances of your application, ensuring that only one instance can modify or access the resource at any given time.

Example of Distributed Locks in Go with Redis


// Import necessary packages
package main

import (
    "fmt"
    "time"
    "github.com/go-redis/redis/v8"
    "golang.org/x/net/context"
)

// Create a Redis client
var ctx = context.Background()

func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr: "localhost:6379", // Redis server address
    })
    
    // Locking function
    lockKey := "lock:myresource"
    lockValue := "unique-lock-value"
    
    // Attempt to acquire the lock
    acquireLock(ctx, rdb, lockKey, lockValue, 10*time.Second)
}

// Function to acquire the lock
func acquireLock(ctx context.Context, rdb *redis.Client, key string, value string, expiration time.Duration) bool {
    // Try to set the lock with an expiration
    result, err := rdb.SetNX(ctx, key, value, expiration).Result()
    if err != nil {
        fmt.Println("Error acquiring lock:", err)
        return false
    }
    if result {
        fmt.Println("Lock acquired")
        // Do work while holding the lock
        defer releaseLock(ctx, rdb, key, value)
        return true
    }
    fmt.Println("Lock not acquired")
    return false
}

// Function to release the lock
func releaseLock(ctx context.Context, rdb *redis.Client, key string, value string) {
    // Use Lua script to safely delete the lock
    luaScript := `
    if redis.call("get", KEYS[1]) == ARGV[1] then
        return redis.call("del", KEYS[1])
    else
        return 0
    end`
    result, err := rdb.Eval(ctx, luaScript, []string{key}, value).Result()
    if err != nil {
        fmt.Println("Error releasing lock:", err)
        return
    }
    if result.(int64) == 1 {
        fmt.Println("Lock released")
    } else {
        fmt.Println("Lock not held, cannot release")
    }
}
    

distributed locks Redis Go Redis client