From a9eabd0f195ebec4f691c0be77114b0f4b438786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Tue, 23 Nov 2021 20:02:15 +0800 Subject: [PATCH] =?UTF-8?q?lease=E5=A2=9E=E5=8A=A0=E6=B0=B8=E4=B9=85?= =?UTF-8?q?=E7=BB=AD=E6=9C=9F=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- middleware/etcd/define.go | 3 +++ middleware/etcd/lease.go | 39 ++++++++++++++++++++++++++++++++++ middleware/etcd/string_test.go | 20 +++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/middleware/etcd/define.go b/middleware/etcd/define.go index 3b1c3aa..3a65392 100644 --- a/middleware/etcd/define.go +++ b/middleware/etcd/define.go @@ -44,3 +44,6 @@ type CancelWatcherHandler func(key string, data interface{}) // TimeoutWatcherHandler 超时之后的回调函数 type TimeoutWatcherHandler func(key string, timeout time.Duration) + +// LeaseKeepALiveHandler 续期成功的处理 +type LeaseKeepALiveHandler func(key string, leaseDetail *clientv3.LeaseKeepAliveResponse) diff --git a/middleware/etcd/lease.go b/middleware/etcd/lease.go index 4cc8966..22f4108 100644 --- a/middleware/etcd/lease.go +++ b/middleware/etcd/lease.go @@ -41,3 +41,42 @@ func LeaseOnce(ctx context.Context, key string, val string, ttl int64) error { } return nil } + +// LeaseKeepAliveForever 无限续租一个key +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 7:40 下午 2021/11/23 +func LeaseKeepAliveForever(ctx context.Context, key string, val string, ttl int64, keepAliveHandler LeaseKeepALiveHandler) error { + if ttl <= 0 { + return errors.New("lease time must be more than 0") + } + if nil == ctx { + ctx = context.TODO() + } + var ( + resp *clientv3.LeaseGrantResponse + respChan <-chan *clientv3.LeaseKeepAliveResponse + err error + ) + // 创建一个5秒的租约 + if resp, err = Client.Grant(ctx, ttl); err != nil { + return errors.New("lease grant error : " + err.Error()) + } + + // ttl 秒钟之后, 这个key就会被移除 + if _, err = Client.Put(context.TODO(), key, val, clientv3.WithLease(resp.ID)); err != nil { + return errors.New("lease key put fail : " + err.Error()) + } + // the key will be kept forever + if respChan, err = Client.KeepAlive(ctx, resp.ID); nil != err { + return errors.New("lease keep alive fail : " + err.Error()) + } + // 监听 chan + for ka := range respChan { + if nil != keepAliveHandler { + keepAliveHandler(key, ka) + } + } + return nil +} diff --git a/middleware/etcd/string_test.go b/middleware/etcd/string_test.go index c7f8c9a..4fb4780 100644 --- a/middleware/etcd/string_test.go +++ b/middleware/etcd/string_test.go @@ -173,3 +173,23 @@ func TestLeaseOnce(t *testing.T) { time.Sleep(time.Second) } } + +// TestLeaseKeepAliveForever ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 7:54 下午 2021/11/23 +func TestLeaseKeepAliveForever(t *testing.T) { + key := "lock" + keepAliveHandler := func(key string, data *clientv3.LeaseKeepAliveResponse) { + fmt.Println(key, data.ID, data.TTL, data.Size(), data.String()) + } + go func() { + fmt.Println(LeaseKeepAliveForever(nil, key, "lock", 10, keepAliveHandler)) + }() + for i := 0; i < 15; i++ { + r, e := Get(nil, key, 1) + fmt.Println("读取", r, e) + time.Sleep(time.Second) + } +}