func doGetMsg(h *InHandler) { var ( cluster *RegCluster err error ) defer func() { h.errOut = err }() // Examine incoming message ------------------------------------- getMsg := h.msgIn clusterID := getMsg.GetClusterID() whichRequested := xu.NewBitMap64(getMsg.GetWhich()) // Take appropriate action -------------------------------------- var tokens []*XLRegMsg_Token whichReturned := xu.NewBitMap64(0) // Put the type assertion within the critical section because on // 2013-12-04 I observed a panic with the error message saying // that the assertion failed because kluster was nil, which should // be impossible. // convert clusterID into a BytesKey bKey, err := ha.NewBytesKey(clusterID) if err == nil { var kluster interface{} h.reg.mu.RLock() // <-- LOCK -------------------------- kluster, err = h.reg.ClustersByID.Find(bKey) if kluster == nil { msg := fmt.Sprintf("doGetMsg: can't find cluster with ID %s", hex.EncodeToString(clusterID)) // DEBUG h.reg.Logger.Printf("%s\n", msg) // END err = e.New(msg) } else { cluster = kluster.(*RegCluster) } h.reg.mu.RUnlock() // <-- UNLOCK ---------------------- } if err == nil { size := cluster.Size() // actual size, not MaxSize if size > MAX_CLUSTER_SIZE { // yes, should be impossible size = MAX_CLUSTER_SIZE } // XXX UNDESIRABLE CAST weHave := xu.LowNMap(uint(size)) whichToSend := whichRequested.Intersection(weHave) for i := uint32(0); i < size; i++ { // XXX UNDESIRABLE CAST if whichToSend.Test(uint(i)) { // they want this one member := cluster.Members[i] token, err := member.Token() if err == nil { tokens = append(tokens, token) // XXX UNDESIRABLE CAST whichReturned = whichReturned.Set(uint(i)) } else { break } } } } if err == nil { // Prepare reply to client -------------------------------------- op := XLRegMsg_ClusterMembers h.msgOut = &XLRegMsg{ Op: &op, ClusterID: clusterID, Which: &whichReturned.Bits, Tokens: tokens, } // Set exit state ----------------------------------------------- h.exitState = JOIN_RCVD // the JOIN is intentional ! } }
// Collect information on all cluster members func (mm *MemberMaker) GetAndMembers() (err error) { if mm.ClusterID == nil { fmt.Printf("** ENTERING GetAndMembers for %s with nil clusterID! **\n", mm.ClusterMember.Node.GetName()) } const MAX_GET = 32 // 2014-01-31: was 16 if mm.Members == nil { mm.Members = make([]*xcl.MemberInfo, mm.ClusterMaxSize) } stillToGet := xu.LowNMap(uint(mm.ClusterMaxSize)) for count := 0; count < MAX_GET && stillToGet.Any(); count++ { var response *XLRegMsg for i := uint32(0); i < uint32(mm.ClusterMaxSize); i++ { if mm.Members[i] != nil { // XXX UNDESIRABLE CAST stillToGet = stillToGet.Clear(uint(i)) } } // Send GET MSG ========================================= op := XLRegMsg_GetCluster request := &XLRegMsg{ Op: &op, ClusterID: mm.ClusterID.Value(), Which: &stillToGet.Bits, } // SHOULD CHECK FOR TIMEOUT err = mm.writeMsg(request) // Process MEMBERS = GET REPLY -------------------------- if err != nil { break } response, err = mm.readMsg() if err != nil { break } op = response.GetOp() // XXX op MUST BE XLRegMsg_Members _ = op if err == nil { id := response.GetClusterID() _ = id // XXX ignore for now which := xu.NewBitMap64(response.GetWhich()) tokens := response.GetTokens() // a slice if which.Any() { offset := 0 for i := uint32(0); i < uint32(mm.ClusterMaxSize); i++ { // XXX UNDESIRABLE CAST if which.Test(uint(i)) { token := tokens[offset] offset++ mm.Members[i], err = NewMemberInfoFromToken( token) if err == nil { // XXX UNDESIRABLE CAST stillToGet = stillToGet.Clear(uint(i)) } } } } if stillToGet.None() { break } time.Sleep(50 * time.Millisecond) // WAS 10 } } if err == nil { selfID := mm.GetNodeID().Value() for i := uint32(0); i < uint32(mm.ClusterMaxSize); i++ { mi := mm.Members[i] if mi == nil { continue } id := mi.Peer.GetNodeID() if id == nil { fmt.Printf("member has no nodeID!\n") } memberID := id.Value() if bytes.Equal(selfID, memberID) { mm.SelfIndex = i break } } } return }