Beispiel #1
0
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 !
	}
}
Beispiel #2
0
// 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
}