func handlePing()

in swim/ping_handler.go [30:80]


func handlePing(node *Node, req *ping) (*ping, error) {
	if !node.Ready() {
		node.EmitEvent(RequestBeforeReadyEvent{PingEndpoint})
		return nil, ErrNodeNotReady
	}

	node.EmitEvent(PingReceiveEvent{
		Local:   node.Address(),
		Source:  req.Source,
		Changes: req.Changes,
	})

	if req.App == "" {
		if node.requiresAppInPing {
			node.logger.WithFields(log.Fields{
				"source": req.Source,
			}).Warn("Rejected ping from unknown ringpop app")
			return nil, errors.New("Pinged ringpop requires app name")
		}
	} else {
		if req.App != node.app {
			node.logger.WithFields(log.Fields{
				"app":    req.App,
				"source": req.Source,
			}).Warn("Rejected ping from wrong ringpop app")
			return nil, errors.New("Pinged ringpop has a different app name")
		}
	}

	node.serverRate.Mark(1)
	node.totalRate.Mark(1)

	node.memberlist.Update(req.Changes)

	changes, fullSync :=
		node.disseminator.IssueAsReceiver(req.Source, req.SourceIncarnation, req.Checksum)

	res := &ping{
		Checksum:          node.memberlist.Checksum(),
		Changes:           changes,
		Source:            node.Address(),
		SourceIncarnation: node.Incarnation(),
	}

	// Start bi-directional full sync.
	if fullSync {
		node.disseminator.tryStartReverseFullSync(req.Source, time.Second)
	}

	return res, nil
}