package clientv3

import (
    pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
)

type (
    Member               pb.Member
    MemberListResponse   pb.MemberListResponse
    MemberAddResponse    pb.MemberAddResponse
    MemberRemoveResponse pb.MemberRemoveResponse
    MemberUpdateResponse pb.MemberUpdateResponse
)

type Cluster interface {
    // MemberList lists the current cluster membership.
    MemberList(ctx context.Context) (*MemberListResponse, error)

    // MemberAdd adds a new member into the cluster.
    MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error)

    // MemberRemove removes an existing member from the cluster.
    MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error)

    // MemberUpdate updates the peer addresses of the member.
    MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error)
}

type cluster struct {
    remote pb.ClusterClient
}

func NewCluster(c *Client) Cluster {
    return &cluster{remote: RetryClusterClient(c)}
}

func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) {
    r := &pb.MemberAddRequest{PeerURLs: peerAddrs}
    resp, err := c.remote.MemberAdd(ctx, r)
    if err == nil {
        return (*MemberAddResponse)(resp), nil
    }
    if isHaltErr(ctx, err) {
        return nil, toErr(ctx, err)
    }
    return nil, toErr(ctx, err)
}

func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error) {
    r := &pb.MemberRemoveRequest{ID: id}
    resp, err := c.remote.MemberRemove(ctx, r)
    if err == nil {
        return (*MemberRemoveResponse)(resp), nil
    }
    if isHaltErr(ctx, err) {
        return nil, toErr(ctx, err)
    }
    return nil, toErr(ctx, err)
}

func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) {
    // it is safe to retry on update.
    for {
        r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs}
        resp, err := c.remote.MemberUpdate(ctx, r, grpc.FailFast(false))
        if err == nil {
            return (*MemberUpdateResponse)(resp), nil
        }
        if isHaltErr(ctx, err) {
            return nil, toErr(ctx, err)
        }
    }
}

func (c *cluster) MemberList(ctx context.Context) (*MemberListResponse, error) {
    // it is safe to retry on list.
    for {
        resp, err := c.remote.MemberList(ctx, &pb.MemberListRequest{}, grpc.FailFast(false))
        if err == nil {
            return (*MemberListResponse)(resp), nil
        }
        if isHaltErr(ctx, err) {
            return nil, toErr(ctx, err)
        }
    }
}

cluster.go的更多相关文章

  1. Node.js:进程、子进程与cluster多核处理模块

    1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...

  2. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...

  3. 【Data Cluster】真机环境下MySQL数据库集群搭建

    真机环境下MySQL-Cluster搭建文档  摘要:本年伊始阶段,由于实验室对不同数据库性能测试需求,才出现MySQL集群搭建.购置主机,交换机,双绞线等一系列准备工作就绪,也就开始集群搭建.起初笔 ...

  4. window下使用Redis Cluster部署Redis集群

    日常的项目很多时候都需要用到缓存.redis算是一个比较好的选择.一般情况下做一个主从就可以满足一些比较小的项目需要.在一些并发量比较大的项目可能就需要用到集群了,redis在Windows下做集群可 ...

  5. helios架构详解(二)客户端架构和cluster

    helios的客户端架构和服务器端类似,只有部分类有所区别(黄色的),下图是客户端的架构 可以看出实际上只有IConnection的俩个实例(TcpConnection.UdpConnection)是 ...

  6. SCVMM中Clone虚拟机失败显示Unsupported Cluster Configuration状态

    在SCVMM进行虚拟机的Clone,虽然失败了,但是Clone出虚拟机却显示在SCVMM控制台的虚拟机的列表中,并且状态是Unsupported Cluster Configuration.无法修复, ...

  7. 浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法

    在我们使用scvmm2012的时候,经常会看到群集状态变成了这样 点开看属性后,我们发现是这样 . 发现了吗?Over-committed,如果翻译过来就是资源过载,或者说资源过量使用了,那么这个状态 ...

  8. redis 学习笔记(7)-cluster 客户端(jedis)代码示例

    上节学习了cluster的搭建及redis-cli终端下如何操作,但是更常用的场景是在程序代码里对cluster读写,这需要redis-client对cluster模式的支持,目前spring-dat ...

  9. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  10. Redis Cluster 分区实现原理

    Redis Cluster本身提供了自动将数据分散到Redis Cluster不同节点的能力,分区实现的关键点问题包括:如何将数据自动地打散到不同的节点,使得不同节点的存储数据相对均匀:如何保证客户端 ...

随机推荐

  1. 一个简单的ruby生成器例子(用连续体Continuation实现)

    ruby中有很多经典的驱动器结构,比如枚举器和生成器等.这次简单介绍下生成器的概念.生成器是按照功能要求,一次产生一个对象,或称之为生成一个对象的方法.ruby中的连续体正好可以用来完成生成器的功能. ...

  2. MQ队列管理器搭建(二)

    MQ级联方式使用场景 使用场景:     如上图所示,Application1与Application2要进行通信或者消息互换,使用MQ中间件作为中介.上图中,Application1与Applica ...

  3. ScrollView的顶部下拉和底部上拉回弹效果

    要实现ScrollView的回弹效果,需要对其进行触摸事件处理.先来看一下简单的效果: 根据Android的View事件分发处理机制,下面对dispatchTouchEvent进行详细分析: 在加载布 ...

  4. Find、FindAll、Where的区别

    Find.FindAll是一个List<T>的方法,返回一个new List<T>包括符合条件的数据 Where是一个linq方法,适用于任意继承了IEnumerable接口的 ...

  5. CPA、CPS、CPM、CPT、CPC 是什么

    http://www.a-edm.com/cpa.html 网络营销之所以越来越受到重视一个主要的原因就是因为“精准”.相比较传统媒体的陈旧广告形式,网络营销能为广告主带来更为确切的效果与回报,更有传 ...

  6. .Net中stirng转Systen.Type的一种实现思路

    今天在上班的过程中,许长时间未联系的大学小伙伴发来消息,带着一个疑问来找我. 他的需求是type动态添加,这对我来说当然很easy,用泛型就好了, 随后,手起刀落,Demo就写出来,如下: 写了一个方 ...

  7. java之Spring实现控制反转

    先来复习一下多态吧,简单点讲,就是一个类的引用可以指向其本身以及其子类的对象. Like these: FatherClass a = new FatherClass(); FatherClass a ...

  8. 如何利用Python网络爬虫爬取微信朋友圈动态--附代码(下)

    前天给大家分享了如何利用Python网络爬虫爬取微信朋友圈数据的上篇(理论篇),今天给大家分享一下代码实现(实战篇),接着上篇往下继续深入. 一.代码实现 1.修改Scrapy项目中的items.py ...

  9. 原生javascript写自己的运动库(匀速运动篇)

    网上有很多JavaScript的运动库,这里和大家分享一下用原生JavaScript一步一步写一个运动函数的过程,如读者有更好的建议欢迎联系作者帮助优化完善代码.这个运动函数完成后,就可以用这个运动函 ...

  10. @Scheduled cron表达式

    一.Cron详解: Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: 1.Seconds Minutes Hours Dayof ...