예제 #1
0
// updates the member list with the slice of changes, applying selectively
func (m *memberlist) Update(changes []Change) (applied []Change) {
	if m.node.Stopped() || len(changes) == 0 {
		return nil
	}

	m.node.emit(MemberlistChangesReceivedEvent{changes})

	m.members.Lock()

	for _, change := range changes {
		member, ok := m.members.byAddress[change.Address]

		// first time member has been seen, take change wholesale
		if !ok {
			m.Apply(change)
			applied = append(applied, change)
			continue
		}

		// if change is local override, reassert member is alive
		if member.localOverride(m.node.Address(), change) {
			overrideChange := Change{
				Source:            change.Source,
				SourceIncarnation: change.SourceIncarnation,
				Address:           change.Address,
				Incarnation:       util.TimeNowMS(),
				Status:            Alive,
				Timestamp:         util.Timestamp(time.Now()),
			}

			m.Apply(overrideChange)
			applied = append(applied, overrideChange)
			continue
		}

		// if non-local override, apply change wholesale
		if member.nonLocalOverride(change) {
			m.Apply(change)
			applied = append(applied, change)
		}
	}

	m.members.Unlock()

	if len(applied) > 0 {
		oldChecksum := m.Checksum()
		m.ComputeChecksum()
		m.node.emit(MemberlistChangesAppliedEvent{
			Changes:     applied,
			OldChecksum: oldChecksum,
			NewChecksum: m.Checksum(),
			NumMembers:  m.NumMembers(),
		})
		m.node.handleChanges(applied)
		m.node.rollup.TrackUpdates(applied)
	}

	return applied
}
예제 #2
0
func (r *updateRollup) AddUpdates(changes []Change) {
	r.buffer.Lock()

	timestamp := time.Now()
	for _, change := range changes {
		change.Timestamp = util.Timestamp(timestamp)
		r.buffer.updates[change.Address] = append(r.buffer.updates[change.Address], change)
	}

	r.buffer.Unlock()
}
예제 #3
0
// makes a change to the member list
func (m *memberlist) MakeChange(address string, incarnation int64, status string) []Change {
	if m.local == nil {
		m.local = &Member{
			Address:     m.node.Address(),
			Incarnation: util.TimeNowMS(),
			Status:      Alive,
		}
	}

	return m.Update([]Change{Change{
		Source:            m.local.Address,
		SourceIncarnation: m.local.Incarnation,
		Address:           address,
		Incarnation:       incarnation,
		Status:            status,
		Timestamp:         util.Timestamp(time.Now()),
	}})
}
예제 #4
0
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/uber/ringpop-go/swim/util"
	"github.com/uber/tchannel-go"
)

var testNow = time.Now()
var testInc = util.TimeNowMS()

var testSuspect = Change{
	Address:           "127.0.0.1:3002",
	Incarnation:       testInc,
	Source:            "127.0.0.1:3001",
	SourceIncarnation: testInc,
	Status:            Suspect,
	Timestamp:         util.Timestamp(testNow),
}

type dummyIter struct{}

func (dummyIter) Next() (*Member, bool) {
	return &Member{
		Address:     "127.0.0.1:3010",
		Status:      Alive,
		Incarnation: testInc,
	}, true
}

type lError struct {
	err error
	sync.Mutex