流言算法--gossip算法

本文介绍了基于pull的gossip算法实现,通过一系列步骤确保状态一致性。协议包括发起者发送Hello消息、接收方回复SendDigest、发起者请求数据并接收响应。文章还提及了关键的数据结构和代码实现细节,如数据集合、nonce管理和随机节点选择。

一个基于pull的gossip算法的实现。最终确保状态一致。
该协议如下:
1)A发起者发送Hello(B唯一标识,nonce)消息到B远程节点(多个)。
2)收Hello信息后发送SendDigest到A节点,其中包含nonce
3)A收到SendDigest,校验数据和nonce,把B作为待发送节点,并封装想要pull的数据SendReq到B节点
4)B收到SendReq发送SendRes到A节点,数据为SendReq不包含的数据
Other peer Initiator
O <——– Hello ————————- O
/|\ ——— Digest <[3,5,8, 10…], NONCE> ——–> /|\
| <——– Request <[3,8], NONCE> —————– |
/ \ ——— Response <[item3, item8], NONCE>——-> / \

一言不合就上源码

 1.  这个是需要实现的接口。定义了上面所说的需要实现的4个接口
// PullAdapter is needed by the PullEngine in order to
// send messages to the remote PullEngine instances.
// The PullEngine expects to be invoked with
// OnHello, OnDigest, OnReq, OnRes when the respective message arrives
// from a remote PullEngine
type PullAdapter interface {
   
   
    // SelectPeers returns a slice of peers which the engine will initiate the protocol with
    SelectPeers() []string

    // Hello sends a hello message to initiate the protocol
    // and returns an NONCE that is expected to be returned
    // in the digest message.
    Hello(dest string, nonce uint64)

    // SendDigest sends a digest to a remote PullEngine.
    // The context parameter specifies the remote engine to send to.
    SendDigest(digest []string, nonce uint64, context interface{
   
   })

    // SendReq sends an array of items to a certain remote PullEngine identified
    // by a string
    SendReq(dest string, items []string, nonce uint64)

    // SendRes sends an array of items to a remote PullEngine identified by a context.
    SendRes(items []string, context interface{
   
   }, nonce uint64)
}
2. 这个是总调度类,初始化时需要传入第一步中的4个接口

stopFlag 结束标识如果为1时,就代表结束
state 一个数据集合
item2owners 需要pull的数据,key代表想要pull的数据,value代表那些节点有这些数据
peers2nonces 一个节点对应一个nonce,key节点唯一标识,value - nonce
nonces2peers 跟peers2nonces相反key,value
acceptingDigests 是否正在接收数据,Digest时锁住
acceptingResponses 是否正在接收数据,Resp时锁住
incomingNONCES 接收到的所有nonce
outgoingNONCES 发送出去的也就是自己生成的所有nonce
注意:processIncomingDigests就是随机挑选一个节点pull数据**

// NewPullEngine creates an instance of a PullEngine with a certain sleep time
// between pull initiations
func NewPullEngine(participant PullAdapter, sleepTime time.Duration) *PullEngine {
    engine := &PullEngine{
        PullAdapter:        participant,
        stopFlag:           int32(0),
        state:              util.NewSet(),
        item2owners:        make(map[string][]string),
        peers2nonces:       make(map[string]uint64),
        nonces2peers:       make(map[uint64]string),
        acceptingDigests:   int32(0),
        acceptingResponses: int32(0),
        incomingNONCES:     util.NewSet(),
        outgoingNONCES:     util.NewSet(),
    }

    go func() {
        for !engine.toDie() {
            time.Sleep(sleepTime)
            if engine.toDie() {
                return
            }
            engine.initiatePull()
        }
    }()

    return engine
}
func (engine *PullEngine) initiatePull() {
    engine.lock.Lock()
    defer engine.lock.Unlock()
    engine.accept
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值