lxd/cluster/heartbeat.go
func heartbeatNode(taskCtx context.Context, address string, cert *shared.CertInfo, raftNodes []db.RaftNode) error {
	logger.Debugf("Sending heartbeat request to %s", address)

	config, err := tlsClientConfig(cert)
	if err != nil {
		return err
	}
	url := fmt.Sprintf("https://%s%s", address, databaseEndpoint)
	client := &http.Client{Transport: &http.Transport{TLSClientConfig: config}}

	buffer := bytes.Buffer{}
	err = json.NewEncoder(&buffer).Encode(raftNodes)
	if err != nil {
		return err
	}

	request, err := http.NewRequest("PUT", url, bytes.NewReader(buffer.Bytes()))
	if err != nil {
		return err
	}
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()
	request = request.WithContext(ctx)
	request.Close = true // Immediately close the connection after the request is done

	// Perform the request asynchronously, so we can abort it if the task context is done.
	errCh := make(chan error)
	go func() {
		response, err := client.Do(request)
		if err != nil {
			errCh <- errors.Wrap(err, "failed to send HTTP request")
			return
		}
		defer response.Body.Close()
		if response.StatusCode != http.StatusOK {
			errCh <- fmt.Errorf("HTTP request failed: %s", response.Status)
			return
		}
		errCh <- nil
	}()

	select {
	case err := <-errCh:
		return err
	case <-taskCtx.Done():
		return taskCtx.Err()
	}
}
func heartbeatNode(taskCtx context.Context, address string, cert *shared.CertInfo, raftNodes []db.RaftNode) error {
	logger.Debugf("Sending heartbeat request to %s", address)

	config, err := tlsClientConfig(cert)
	if err != nil {
		return err
	}
	url := fmt.Sprintf("https://%s%s", address, databaseEndpoint)
	client := &http.Client{Transport: &http.Transport{TLSClientConfig: config}}

	buffer := bytes.Buffer{}
	err = json.NewEncoder(&buffer).Encode(raftNodes)
	if err != nil {
		return err
	}

	request, err := http.NewRequest("PUT", url, bytes.NewReader(buffer.Bytes()))
	if err != nil {
		return err
	}
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()
	request = request.WithContext(ctx)
	request.Close = true // Immediately close the connection after the request is done

	// Perform the request asynchronously, so we can abort it if the task context is done.
	errCh := make(chan error)
	go func() {
		response, err := client.Do(request)
		if err != nil {
			errCh <- errors.Wrap(err, "failed to send HTTP request")
			return
		}
		defer response.Body.Close()
		if response.StatusCode != http.StatusOK {
			errCh <- fmt.Errorf("HTTP request failed: %s", response.Status)
			return
		}
		errCh <- nil
	}()

	select {
	case err := <-errCh:
		return err
	case <-taskCtx.Done():
		return taskCtx.Err()
	}
}
// Perform a single heartbeat request against the node with the given address.