func (s *SyslogSink) Run(inputChan <-chan *events.Envelope) { syslogIdentifier := s.Identifier() s.logger.Infof("Syslog Sink %s: Running.", syslogIdentifier) defer s.logger.Errorf("Syslog Sink %s: Stopped.", syslogIdentifier) backoffStrategy := retrystrategy.NewExponentialRetryStrategy() context := truncatingbuffer.NewLogAllowedContext(s.dropsondeOrigin, syslogIdentifier) buffer := sinks.RunTruncatingBuffer(inputChan, s.messageDrainBufferSize, context, s.logger, s.disconnectChannel) timer := time.NewTimer(backoffStrategy(0)) connected := false defer timer.Stop() defer s.syslogWriter.Close() s.logger.Debugf("Syslog Sink %s: Starting loop. Current backoff: %v", syslogIdentifier, backoffStrategy(0)) for { s.logger.Debugf("Syslog Sink %s: Waiting for activity\n", syslogIdentifier) select { case <-s.disconnectChannel: return case messageEnvelope, ok := <-buffer.GetOutputChannel(): if !ok { s.logger.Debugf("Syslog Sink %s: Closed listener channel detected. Closing.\n", syslogIdentifier) return } numberOfTries := 0 for { for !connected { s.logger.Debugf("Syslog Sink %s: Not connected. Trying to connect.", syslogIdentifier) err := s.syslogWriter.Connect() if err == nil { s.logger.Infof("Syslog Sink %s: successfully connected.", syslogIdentifier) connected = true break } sleepDuration := backoffStrategy(numberOfTries) errorMsg := fmt.Sprintf("Syslog Sink %s: Error when dialing out. Backing off for %v. Err: %v", syslogIdentifier, sleepDuration, err) s.handleSendError(errorMsg, s.appId) timer.Reset(sleepDuration) select { case <-s.disconnectChannel: return case <-timer.C: } numberOfTries++ } err := s.sendLogMessage(messageEnvelope.GetLogMessage()) if err == nil { connected = true break } s.logger.Debugf("Syslog Sink %s: Error when trying to send data to sink. Backing off. Err: %v\n", syslogIdentifier, err) connected = false numberOfTries++ } } } }
func (s *SyslogSink) Run(inputChan <-chan *events.Envelope) { s.logger.Infof("Syslog Sink %s: Running.", s.drainUrl) defer s.logger.Errorf("Syslog Sink %s: Stopped.", s.drainUrl) backoffStrategy := retrystrategy.NewExponentialRetryStrategy() filteredChan := make(chan *events.Envelope) go func() { defer close(filteredChan) for { select { case v, ok := <-inputChan: if !ok { return } if v.GetEventType() != events.Envelope_LogMessage { continue } filteredChan <- v case <-s.disconnectChannel: return } } }() buffer := sinks.RunTruncatingBuffer(filteredChan, s.messageDrainBufferSize, s.logger, s.dropsondeOrigin, s.Identifier()) timer := time.NewTimer(backoffStrategy(0)) connected := false defer timer.Stop() defer s.syslogWriter.Close() s.logger.Debugf("Syslog Sink %s: Starting loop. Current backoff: %v", s.drainUrl, backoffStrategy(0)) for { s.logger.Debugf("Syslog Sink %s: Waiting for activity\n", s.drainUrl) select { case <-s.disconnectChannel: return case messageEnvelope, ok := <-buffer.GetOutputChannel(): if !ok { s.logger.Debugf("Syslog Sink %s: Closed listener channel detected. Closing.\n", s.drainUrl) return } // Some metrics will not be filter and can get to here (i.e.: TruncatingBuffer dropped message metrics) if messageEnvelope.GetEventType() == events.Envelope_LogMessage { numberOfTries := 0 for { for !connected { s.logger.Debugf("Syslog Sink %s: Not connected. Trying to connect.", s.drainUrl) err := s.syslogWriter.Connect() if err == nil { s.logger.Infof("Syslog Sink %s: successfully connected.", s.drainUrl) connected = true break } sleepDuration := backoffStrategy(numberOfTries) errorMsg := fmt.Sprintf("Syslog Sink %s: Error when dialing out. Backing off for %v. Err: %v", s.drainUrl, sleepDuration, err) s.handleSendError(errorMsg, s.appId, s.drainUrl) timer.Reset(sleepDuration) select { case <-s.disconnectChannel: return case <-timer.C: } numberOfTries++ } err := s.sendLogMessage(messageEnvelope.GetLogMessage()) if err == nil { connected = true break } s.logger.Debugf("Syslog Sink %s: Error when trying to send data to sink. Backing off. Err: %v\n", s.drainUrl, err) connected = false numberOfTries++ } } } } }
{4, 8000}, {5, 16000}, {11, 1024000}, //1.024s {12, 2048000}, //2.048s {20, 524288000}, //8m and a bit {21, 1048576000}, //17m28.576s {22, 2097152000}, //34m57.152s {23, 4194304000}, //1h9m54.304s {24, 4194304000}, //1h9m54.304s {25, 4194304000}, //1h9m54.304s {26, 4194304000}, //1h9m54.304s } It("backs off exponentially with different random seeds", func() { rand.Seed(1) strategy := retrystrategy.NewExponentialRetryStrategy() otherStrategy := retrystrategy.NewExponentialRetryStrategy() Expect(strategy(0).String()).To(Equal("1ms")) Expect(otherStrategy(0).String()).To(Equal("1ms")) var backoff time.Duration var oldBackoff time.Duration var otherBackoff time.Duration var otherOldBackoff time.Duration for _, bt := range backoffTests { delta := int(bt.expected / 10) for i := 0; i < 10; i++ { backoff = strategy(bt.backoffCount) otherBackoff = otherStrategy(bt.backoffCount)
func (s *SyslogSink) Run(inputChan <-chan *events.Envelope) { s.Infof("Syslog Sink %s: Running.", s.drainUrl) defer s.Errorf("Syslog Sink %s: Stopped.", s.drainUrl) backoffStrategy := retrystrategy.NewExponentialRetryStrategy() numberOfTries := 0 filteredChan := make(chan *events.Envelope) go func() { defer close(filteredChan) for { select { case v, ok := <-inputChan: if !ok { return } if v.GetEventType() != events.Envelope_LogMessage { continue } filteredChan <- v case <-s.disconnectChannel: return } } }() buffer := sinks.RunTruncatingBuffer(filteredChan, 100, s.Logger, s.dropsondeOrigin) timer := time.NewTimer(backoffStrategy(numberOfTries)) connected := false defer timer.Stop() defer s.syslogWriter.Close() for { s.Debugf(starting_loop_debug, s.drainUrl, backoffStrategy(numberOfTries)) timer.Reset(backoffStrategy(numberOfTries)) select { case <-s.disconnectChannel: return case <-timer.C: } if !connected { s.Debugf(dialing_debug_string, s.drainUrl) err := s.syslogWriter.Connect() if err != nil { numberOfTries++ errorMsg := fmt.Sprintf(dial_error_debug_string, s.drainUrl, backoffStrategy(numberOfTries), err) s.handleSendError(errorMsg, s.appId, s.drainUrl) continue } s.Infof("Syslog Sink %s: successfully connected.", s.drainUrl) connected = true } s.Debugf("Syslog Sink %s: Waiting for activity\n", s.drainUrl) select { case <-s.disconnectChannel: return case messageEnvelope, ok := <-buffer.GetOutputChannel(): droppedMessages := buffer.GetDroppedMessageCount() if droppedMessages != 0 { s.UpdateDroppedMessageCount(droppedMessages) } if !ok { s.Debugf("Syslog Sink %s: Closed listener channel detected. Closing.\n", s.drainUrl) return } s.Debugf("Syslog Sink:Run: Received %s message from %s at %d. Sending data.", messageEnvelope.GetEventType().String(), messageEnvelope.GetOrigin(), messageEnvelope.Timestamp) connected = s.sendMessage(messageEnvelope) if connected { numberOfTries = 0 } else { numberOfTries++ } } } }