(e raftpb.Entry)
| 488 | } |
| 489 | |
| 490 | func (n *node) applyConfChange(e raftpb.Entry) { |
| 491 | var cc raftpb.ConfChange |
| 492 | if err := cc.Unmarshal(e.Data); err != nil { |
| 493 | glog.Errorf("While unmarshalling confchange: %+v", err) |
| 494 | } |
| 495 | |
| 496 | if cc.Type == raftpb.ConfChangeRemoveNode { |
| 497 | if cc.NodeID == n.Id { |
| 498 | glog.Fatalf("I [id:%#x group:0] have been removed. Goodbye!", n.Id) |
| 499 | } |
| 500 | n.DeletePeer(cc.NodeID) |
| 501 | n.server.removeZero(cc.NodeID) |
| 502 | |
| 503 | } else if cc.Type == raftpb.ConfChangeUpdateNode && len(cc.Context) > 0 { |
| 504 | // ConfChangeUpdateNode is a Raft-provided mechanism for updating node |
| 505 | // metadata (e.g. addresses) without changing cluster membership. It is |
| 506 | // a no-op inside the Raft library; the application is responsible for |
| 507 | // interpreting the Context bytes. We use it to fix stale Zero addresses |
| 508 | // that were baked into the WAL at initial bootstrap. |
| 509 | var rc pb.RaftContext |
| 510 | x.Check(proto.Unmarshal(cc.Context, &rc)) |
| 511 | |
| 512 | // Drop the stale pool before connecting to the new address so that |
| 513 | // repeated dial errors to the old address are eliminated immediately. |
| 514 | if oldMember, ok := n.server.membershipState().GetZeros()[rc.Id]; ok { |
| 515 | if oldMember.GetAddr() != rc.Addr { |
| 516 | conn.GetPools().Remove(oldMember.GetAddr()) |
| 517 | } |
| 518 | } |
| 519 | go n.Connect(rc.Id, rc.Addr) |
| 520 | |
| 521 | m := &pb.Member{Id: rc.Id, Addr: rc.Addr, GroupId: 0, Learner: rc.IsLearner} |
| 522 | n.server.storeZero(m) |
| 523 | glog.Infof("Applied ConfChangeUpdateNode for Zero %#x: addr=%q", rc.Id, rc.Addr) |
| 524 | |
| 525 | } else if len(cc.Context) > 0 { |
| 526 | var rc pb.RaftContext |
| 527 | x.Check(proto.Unmarshal(cc.Context, &rc)) |
| 528 | go n.Connect(rc.Id, rc.Addr) |
| 529 | |
| 530 | m := &pb.Member{ |
| 531 | Id: rc.Id, |
| 532 | Addr: rc.Addr, |
| 533 | GroupId: 0, |
| 534 | Learner: rc.IsLearner, |
| 535 | } |
| 536 | for _, member := range n.server.membershipState().Removed { |
| 537 | // It is not recommended to reuse RAFT ids. |
| 538 | if member.GroupId == 0 && m.Id == member.Id { |
| 539 | err := errors.Errorf("REUSE_RAFTID: Reusing removed id: %d.\n", m.Id) |
| 540 | n.DoneConfChange(cc.ID, err) |
| 541 | // Cancel configuration change. |
| 542 | cc.NodeID = raft.None |
| 543 | n.Raft().ApplyConfChange(cc) |
| 544 | return |
| 545 | } |
| 546 | } |
| 547 |
no test coverage detected