github.com/Axway/agent-sdk@v1.1.101/pkg/agent/poller/client.go (about)

     1  package poller
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/Axway/agent-sdk/pkg/agent/events"
     8  	"github.com/Axway/agent-sdk/pkg/agent/handler"
     9  	"github.com/Axway/agent-sdk/pkg/config"
    10  	"github.com/Axway/agent-sdk/pkg/harvester"
    11  	"github.com/Axway/agent-sdk/pkg/util/errors"
    12  	hc "github.com/Axway/agent-sdk/pkg/util/healthcheck"
    13  	"github.com/Axway/agent-sdk/pkg/watchmanager/proto"
    14  )
    15  
    16  // PollClient is a client for polling harvester
    17  type PollClient struct {
    18  	apiClient          events.APIClient
    19  	handlers           []handler.Handler
    20  	interval           time.Duration
    21  	listener           events.Listener
    22  	newListener        events.NewListenerFunc
    23  	onClientStop       onClientStopCb
    24  	onStreamConnection func()
    25  	poller             *pollExecutor
    26  	newPollManager     newPollExecutorFunc
    27  	harvesterConfig    harvesterConfig
    28  	mutex              sync.RWMutex
    29  	initialized        bool
    30  }
    31  
    32  type harvesterConfig struct {
    33  	sequence      events.SequenceProvider
    34  	topicSelfLink string
    35  	hClient       harvester.Harvest
    36  }
    37  
    38  type onClientStopCb func()
    39  
    40  // NewPollClient creates a polling client
    41  func NewPollClient(
    42  	apiClient events.APIClient,
    43  	cfg config.CentralConfig,
    44  	handlers []handler.Handler,
    45  	options ...ClientOpt,
    46  ) (*PollClient, error) {
    47  	pc := &PollClient{
    48  		apiClient:      apiClient,
    49  		handlers:       handlers,
    50  		interval:       cfg.GetPollInterval(),
    51  		listener:       nil,
    52  		newListener:    events.NewEventListener,
    53  		newPollManager: newPollExecutor,
    54  		poller:         nil,
    55  	}
    56  
    57  	for _, opt := range options {
    58  		opt(pc)
    59  	}
    60  
    61  	return pc, nil
    62  }
    63  
    64  // Start the polling client
    65  func (p *PollClient) Start() error {
    66  	eventCh, eventErrorCh := make(chan *proto.Event), make(chan error)
    67  
    68  	p.mutex.Lock()
    69  
    70  	p.listener = p.newListener(
    71  		eventCh,
    72  		p.apiClient,
    73  		p.harvesterConfig.sequence,
    74  		p.handlers...,
    75  	)
    76  
    77  	p.poller = p.newPollManager(
    78  		p.interval,
    79  		withOnStop(p.onClientStop),
    80  		withHarvester(p.harvesterConfig),
    81  	)
    82  	p.mutex.Unlock()
    83  	listenCh := p.listener.Listen()
    84  	p.poller.RegisterWatch(eventCh, eventErrorCh)
    85  
    86  	if p.onStreamConnection != nil {
    87  		p.onStreamConnection()
    88  	}
    89  
    90  	p.mutex.Lock()
    91  	p.initialized = true
    92  	p.mutex.Unlock()
    93  
    94  	select {
    95  	case err := <-listenCh:
    96  		return err
    97  	case err := <-eventErrorCh:
    98  		return err
    99  	}
   100  }
   101  
   102  // Status returns an error if the poller is not running
   103  func (p *PollClient) Status() error {
   104  	p.mutex.RLock()
   105  	defer p.mutex.RUnlock()
   106  	if p.initialized {
   107  		if ok := p.poller.Status(); !ok {
   108  			return errors.ErrHarvesterConnection
   109  		}
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  // Stop stops the streamer
   116  func (p *PollClient) Stop() {
   117  	p.poller.Stop()
   118  	p.listener.Stop()
   119  }
   120  
   121  // Healthcheck returns a healthcheck
   122  func (p *PollClient) Healthcheck(_ string) *hc.Status {
   123  	err := p.Status()
   124  	if err != nil {
   125  		return &hc.Status{
   126  			Result:  hc.FAIL,
   127  			Details: err.Error(),
   128  		}
   129  	}
   130  	return &hc.Status{
   131  		Result: hc.OK,
   132  	}
   133  }