func sendPingWithChanges()

in swim/ping_sender.go [61:122]


func sendPingWithChanges(node *Node, target string, changes []Change, timeout time.Duration) (*ping, error) {
	req := ping{
		Checksum:          node.memberlist.Checksum(),
		Changes:           changes,
		Source:            node.Address(),
		SourceIncarnation: node.Incarnation(),
		App:               node.app,
	}

	node.EmitEvent(PingSendEvent{
		Local:   node.Address(),
		Remote:  target,
		Changes: req.Changes,
	})

	logging.Logger("ping").WithFields(log.Fields{
		"local":   node.Address(),
		"remote":  target,
		"changes": req.Changes,
	}).Debug("ping send")

	ctx, cancel := shared.NewTChannelContext(timeout)
	defer cancel()

	peer := node.channel.Peers().GetOrAdd(target)
	startTime := time.Now()

	// send the ping
	errC := make(chan error, 1)
	res := &ping{}
	go func() {
		errC <- json.CallPeer(ctx, peer, node.service, "/protocol/ping", req, res)
	}()

	// get result or timeout
	var err error
	select {
	case err = <-errC:
	case <-ctx.Done():
		err = errors.New("ping timed out")
	}

	if err != nil {
		// ping failed
		logging.Logger("ping").WithFields(log.Fields{
			"local":  node.Address(),
			"remote": target,
			"error":  err,
		}).Debug("ping failed")

		return nil, err
	}

	node.EmitEvent(PingSendCompleteEvent{
		Local:    node.Address(),
		Remote:   target,
		Changes:  req.Changes,
		Duration: time.Now().Sub(startTime),
	})

	return res, err
}