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

     1  package agent
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/Axway/agent-sdk/pkg/jobs"
     8  	hc "github.com/Axway/agent-sdk/pkg/util/healthcheck"
     9  )
    10  
    11  // constants for retry interval for stream job
    12  const (
    13  	defaultRetryInterval   = 5 * time.Second
    14  	maxRetryInterval       = 5 * time.Minute
    15  	maxNumRetryForInterval = 3
    16  )
    17  
    18  // eventsJob interface for a job to execute to retrieve events in either stream or poll mode
    19  type eventsJob interface {
    20  	Start() error
    21  	Status() error
    22  	Stop()
    23  	Healthcheck(_ string) *hc.Status
    24  }
    25  
    26  // eventProcessorJob job wrapper for a streamerClient that starts a stream and an event manager.
    27  type eventProcessorJob struct {
    28  	streamer      eventsJob
    29  	stop          chan interface{}
    30  	jobID         string
    31  	retryInterval time.Duration
    32  	numRetry      int
    33  	name          string
    34  	mutex         sync.RWMutex
    35  }
    36  
    37  // newEventProcessorJob creates a job for the streamerClient
    38  func newEventProcessorJob(eventJob eventsJob, name string) jobs.Job {
    39  	streamJob := &eventProcessorJob{
    40  		streamer:      eventJob,
    41  		stop:          make(chan interface{}, 1),
    42  		retryInterval: defaultRetryInterval,
    43  		numRetry:      0,
    44  		name:          name,
    45  	}
    46  
    47  	jobID, _ := jobs.RegisterDetachedChannelJobWithName(streamJob, streamJob.stop, name)
    48  	streamJob.mutex.Lock()
    49  	streamJob.jobID = jobID
    50  	streamJob.mutex.Unlock()
    51  
    52  	jobs.RegisterIntervalJobWithName(newCentralHealthCheckJob(eventJob), time.Second*3, "Central Health Check")
    53  
    54  	return streamJob
    55  }
    56  
    57  // Execute starts the stream
    58  func (j *eventProcessorJob) Execute() error {
    59  	go func() {
    60  		<-j.stop
    61  		j.streamer.Stop()
    62  		j.renewRegistration()
    63  	}()
    64  
    65  	return j.streamer.Start()
    66  }
    67  
    68  // Status gets the status
    69  func (j *eventProcessorJob) Status() error {
    70  	status := j.streamer.Status()
    71  	if status == nil {
    72  		j.retryInterval = defaultRetryInterval
    73  		j.numRetry = 0
    74  	}
    75  	return status
    76  }
    77  
    78  // Ready checks if the job to start the stream is ready
    79  func (j *eventProcessorJob) Ready() bool {
    80  	return true
    81  }
    82  
    83  func (j *eventProcessorJob) renewRegistration() {
    84  	defer time.AfterFunc(j.retryInterval, func() {
    85  		j.mutex.Lock()
    86  		defer j.mutex.Unlock()
    87  
    88  		jobID, _ := jobs.RegisterDetachedChannelJobWithName(j, j.stop, j.name)
    89  		j.jobID = jobID
    90  	})
    91  
    92  	j.mutex.Lock()
    93  	defer j.mutex.Unlock()
    94  
    95  	if j.jobID != "" {
    96  		jobs.UnregisterJob(j.jobID)
    97  		j.jobID = ""
    98  		j.numRetry++
    99  		if j.numRetry == maxNumRetryForInterval {
   100  			j.numRetry = 0
   101  			j.retryInterval = j.retryInterval * 2
   102  			if j.retryInterval > maxRetryInterval {
   103  				j.retryInterval = defaultRetryInterval
   104  			}
   105  		}
   106  	}
   107  }