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 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型
  • ¥50 buildozer打包kivy app失败
  • ¥30 在vs2022里运行python代码
  • ¥15 不同尺寸货物如何寻找合适的包装箱型谱
  • ¥15 求解 yolo算法问题