dtzjvj3915 2016-11-29 19:50
浏览 112
已采纳

两个客户在领事馆获得相同的锁

I have the following code:

package publicservice

import (
    "time"
    "github.com/hashicorp/consul/api"
    "github.com/hashicorp/consul/testutil"
    "testing"
)

func TestAcquireLock(t *testing.T) {
    consul := testutil.NewTestServer(t)
    defer consul.Stop()

    firstClient, err := api.NewClient(&api.Config{
        Address: consul.HTTPAddr,
    })

    if err != nil {
        t.Fatalf("failed to create first client with %v", err)
    }

    secondClient, err := api.NewClient(&api.Config{
        Address: consul.HTTPAddr,
    })

    if err != nil {
        t.Fatalf("failed to create second client with %v", err)
    }

    lockKey := "sample-lock-key"

    firstLock, err := firstClient.LockOpts(&api.LockOptions{
        Key: lockKey,
    })

    if err != nil {
        t.Fatalf("failed to create first lock %v", err)
    }

    _, err = firstLock.Lock(nil)

    if err != nil {
        t.Fatalf("failed to acquire first lock %v", err)
    }

    defer firstLock.Unlock()

    secondLock, err := secondClient.LockOpts(&api.LockOptions{
        Key: lockKey,
        LockTryOnce: true,
        LockWaitTime: time.Second,
    })

    if err != nil {
        t.Fatalf("failed to create second lock %v", err)
    }

    _, err = secondLock.Lock(nil)

    if err == nil {
        t.Fatal("should not have acquired lock here")
    }
}

And when I run it this second lock call never fails, even if it should fail since the lock is already being held by another client as it can be seen by the logs:

2016/11/29 14:46:25 [DEBUG] http: Request GET /v1/catalog/nodes (1.115897356s) from=127.0.0.1:50492
2016/11/29 14:46:25 [DEBUG] http: Request PUT /v1/session/create (939.436µs) from=127.0.0.1:50493
2016/11/29 14:46:25 [DEBUG] http: Request GET /v1/kv/sample-lock-key?wait=15000ms (269.823µs) from=127.0.0.1:50493
2016/11/29 14:46:25 [DEBUG] http: Request PUT /v1/kv/sample-lock-key?acquire=aa8fb351-6b6e-8e17-f8d9-fb265c497a9f&flags=3304740253564472344 (899.564µs) from=127.0.0.1:50493
2016/11/29 14:46:25 [DEBUG] http: Request GET /v1/kv/sample-lock-key?consistent= (112.87µs) from=127.0.0.1:50493
2016/11/29 14:46:25 [DEBUG] http: Request PUT /v1/session/create (595.554µs) from=127.0.0.1:50494
2016/11/29 14:46:25 [DEBUG] http: Request GET /v1/kv/sample-lock-key?wait=1000ms (38.602µs) from=127.0.0.1:50494
2016/11/29 14:46:26 [DEBUG] http: Request GET /v1/kv/sample-lock-key?index=7&wait=999ms (1.007117154s) from=127.0.0.1:50494
2016/11/29 14:46:26 [DEBUG] http: Request PUT /v1/session/destroy/fd83b8f8-1757-d9d7-6f0e-5defaf26b886 (1.549558ms) from=127.0.0.1:50494
2016/11/29 14:46:26 [DEBUG] http: Request PUT /v1/kv/sample-lock-key?flags=3304740253564472344&release=aa8fb351-6b6e-8e17-f8d9-fb265c497a9f (1.56451ms) from=127.0.0.1:50495
2016/11/29 14:46:26 [DEBUG] http: Request GET /v1/kv/sample-lock-key?consistent=&index=7 (1.010637359s) from=127.0.0.1:50493

What am I missing here? Is there something else I must do to make sure the second client doesn't acquire the lock?

  • 写回答

1条回答 默认 最新

  • duanchuan6350 2016-11-29 21:29
    关注

    Issue was that you have to check the channel that's returned from Lock, if the lock is already held the channel is nil:

    package publicservice
    
    import (
        "time"
        "github.com/hashicorp/consul/api"
        "github.com/hashicorp/consul/testutil"
        "testing"
        "github.com/xtgo/uuid"
    )
    
    func TestAcquireLock(t *testing.T) {
        consul := testutil.NewTestServer(t)
        defer consul.Stop()
    
        firstClient, err := api.NewClient(&api.Config{
            Address: consul.HTTPAddr,
        })
    
        if err != nil {
            t.Fatalf("failed to create first client with %v", err)
        }
    
        secondClient, err := api.NewClient(&api.Config{
            Address: consul.HTTPAddr,
        })
    
        if err != nil {
            t.Fatalf("failed to create second client with %v", err)
        }
    
        lockKey := "sample-lock-key"
    
        firstLock, err := firstClient.LockOpts(&api.LockOptions{
            Key: lockKey,
            SessionName: uuid.NewRandom().String(),
        })
    
        if err != nil {
            t.Fatalf("failed to create first lock %v", err)
        }
    
        firstResult, err := firstLock.Lock(nil)
    
        t.Logf("=====> result for first lock is %v", firstResult)
    
        if err != nil {
            t.Fatalf("failed to acquire first lock %v", err)
        }
    
        defer firstLock.Unlock()
    
        secondLock, err := secondClient.LockOpts(&api.LockOptions{
            Key: lockKey,
            LockTryOnce: true,
            LockWaitTime: time.Second,
            SessionName: uuid.NewRandom().String(),
        })
    
        if err != nil {
            t.Fatalf("failed to create second lock %v", err)
        }
    
        secondResult, err := secondLock.Lock(nil)
    
        if secondResult != nil || err != nil {
            t.Fatal("should not have acquired lock here")
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 51单片机中C语言怎么做到下面类似的功能的函数(相关搜索:c语言)
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题