github.com/crowdsecurity/crowdsec@v1.6.1/pkg/apiclient/heartbeat.go (about)

     1  package apiclient
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  	"time"
     8  
     9  	log "github.com/sirupsen/logrus"
    10  	tomb "gopkg.in/tomb.v2"
    11  
    12  	"github.com/crowdsecurity/go-cs-lib/trace"
    13  )
    14  
    15  type HeartBeatService service
    16  
    17  func (h *HeartBeatService) Ping(ctx context.Context) (bool, *Response, error) {
    18  	u := fmt.Sprintf("%s/heartbeat", h.client.URLPrefix)
    19  
    20  	req, err := h.client.NewRequest(http.MethodGet, u, nil)
    21  	if err != nil {
    22  		return false, nil, err
    23  	}
    24  
    25  	resp, err := h.client.Do(ctx, req, nil)
    26  	if err != nil {
    27  		return false, resp, err
    28  	}
    29  
    30  	return true, resp, nil
    31  }
    32  
    33  func (h *HeartBeatService) StartHeartBeat(ctx context.Context, t *tomb.Tomb) {
    34  	t.Go(func() error {
    35  		defer trace.CatchPanic("crowdsec/apiClient/heartbeat")
    36  		hbTimer := time.NewTicker(1 * time.Minute)
    37  		for {
    38  			select {
    39  			case <-hbTimer.C:
    40  				log.Debug("heartbeat: sending heartbeat")
    41  
    42  				ok, resp, err := h.Ping(ctx)
    43  				if err != nil {
    44  					log.Errorf("heartbeat error: %s", err)
    45  					continue
    46  				}
    47  
    48  				resp.Response.Body.Close()
    49  				if resp.Response.StatusCode != http.StatusOK {
    50  					log.Errorf("heartbeat unexpected return code: %d", resp.Response.StatusCode)
    51  					continue
    52  				}
    53  
    54  				if !ok {
    55  					log.Errorf("heartbeat returned false")
    56  					continue
    57  				}
    58  			case <-t.Dying():
    59  				log.Debugf("heartbeat: stopping")
    60  				hbTimer.Stop()
    61  				return nil
    62  			}
    63  		}
    64  	})
    65  }