func (m *LoadBalancerMode) onMessage(client ProtocolClient, msg eventsMessage) { if msg.event != nil { if err := client.PublishEvent(msg.event); err != nil { msg.attemptsLeft-- m.onFail(msg, err) return } } else { events := msg.events total := len(events) var backoffCount uint for len(events) > 0 { var err error events, err = client.PublishEvents(events) if err != nil { msg.attemptsLeft-- // reset attempt count if subset of messages has been processed if len(events) < total { msg.attemptsLeft = m.maxAttempts } if err != ErrTempBulkFailure { // retry non-published subset of events in batch msg.events = events m.onFail(msg, err) return } if m.maxAttempts > 0 && msg.attemptsLeft <= 0 { // no more attempts left => drop outputs.SignalFailed(msg.signaler, err) return } // wait before retry backoff := time.Duration(int64(m.waitRetry) * (1 << backoffCount)) if backoff > m.maxWaitRetry { backoff = m.maxWaitRetry } else { backoffCount++ } select { case <-m.done: // shutdown outputs.SignalFailed(msg.signaler, err) return case <-time.After(backoff): } // reset total count for temporary failure loop total = len(events) } } } outputs.SignalCompleted(msg.signaler) }
func (c *console) PublishEvent( s outputs.Signaler, ts time.Time, event common.MapStr, ) error { var jsonEvent []byte var err error if c.pretty { jsonEvent, err = json.MarshalIndent(event, "", " ") } else { jsonEvent, err = json.Marshal(event) } if err != nil { logp.Err("Fail to convert the event to JSON: %s", err) outputs.SignalCompleted(s) return err } if err = writeBuffer(jsonEvent); err != nil { goto fail } if err = writeBuffer([]byte{'\n'}); err != nil { goto fail } outputs.SignalCompleted(s) return nil fail: outputs.SignalFailed(s, err) return err }
func (mh *testMessageHandler) acknowledgeMessage(m message) { if mh.response == CompletedResponse { outputs.SignalCompleted(m.context.signal) } else { outputs.SignalFailed(m.context.signal, nil) } }
func (c *console) PublishEvent( s outputs.Signaler, opts outputs.Options, event common.MapStr, ) error { var jsonEvent []byte var err error if c.config.Pretty { jsonEvent, err = json.MarshalIndent(event, "", " ") } else { jsonEvent, err = json.Marshal(event) } if err != nil { logp.Err("Fail to convert the event to JSON: %s", err) outputs.SignalCompleted(s) return err } if err = writeBuffer(jsonEvent); err != nil { goto fail } if err = writeBuffer([]byte{'\n'}); err != nil { goto fail } outputs.SignalCompleted(s) return nil fail: if opts.Guaranteed { logp.Critical("Unable to publish events to console: %v", err) } outputs.SignalFailed(s, err) return err }
func (m *LoadBalancerMode) onFail(msg eventsMessage, err error) { logp.Info("Error publishing events (retrying): %s", err) if ok := m.forwardEvent(m.retries, msg); !ok { outputs.SignalFailed(msg.signaler, err) } }
// publish is used to publish events using the configured protocol client. // It provides general error handling and back off support used on failed // send attempts. To be used by PublishEvent and PublishEvents. // The send callback will try to progress sending traffic and returns kind of // progress made in ok or resetFail. If ok is set to true, send finished // processing events. If ok is false but resetFail is set, send was partially // successful. If send was partially successful, the fail counter is reset thus up // to maxAttempts send attempts without any progress might be executed. func (s *SingleConnectionMode) publish( signaler outputs.Signaler, opts outputs.Options, send func() (ok bool, resetFail bool), ) error { fails := 0 var backoffCount uint var err error guaranteed := opts.Guaranteed || s.maxAttempts == 0 for !s.closed && (guaranteed || fails < s.maxAttempts) { ok := false resetFail := false if err := s.connect(); err != nil { logp.Info("Connecting error publishing events (retrying): %s", err) goto sendFail } ok, resetFail = send() if !ok { goto sendFail } debug("send completed") outputs.SignalCompleted(signaler) return nil sendFail: fails++ if resetFail { debug("reset fails") fails = 0 } if !guaranteed && (s.maxAttempts > 0 && fails == s.maxAttempts) { // max number of attempts reached debug("max number of attempts reached") break } logp.Info("send fail") backoff := time.Duration(int64(s.waitRetry) * (1 << backoffCount)) if backoff > s.maxWaitRetry { backoff = s.maxWaitRetry } else { backoffCount++ } logp.Info("backoff retry: %v", backoff) time.Sleep(backoff) } debug("messages dropped") messagesDropped.Add(1) outputs.SignalFailed(signaler, err) return nil }
func (out *redisOutput) BulkPublish( signal outputs.Signaler, ts time.Time, events []common.MapStr, ) error { if !out.connected { logp.Debug("output_redis", "Droping pkt ...") return errors.New("Not connected") } command := "RPUSH" if out.DataType == RedisChannelType { command = "PUBLISH" } if len(events) == 1 { // single event event := events[0] jsonEvent, err := json.Marshal(event) if err != nil { logp.Err("Fail to convert the event to JSON: %s", err) outputs.SignalCompleted(signal) return err } _, err = out.Conn.Do(command, out.Index, string(jsonEvent)) outputs.Signal(signal, err) out.onFail(err) return err } for _, event := range events { jsonEvent, err := json.Marshal(event) if err != nil { logp.Err("Fail to convert the event to JSON: %s", err) continue } err = out.Conn.Send(command, out.Index, string(jsonEvent)) if err != nil { outputs.SignalFailed(signal, err) out.onFail(err) return err } } if err := out.Conn.Flush(); err != nil { outputs.Signal(signal, err) out.onFail(err) return err } _, err := out.Conn.Receive() outputs.Signal(signal, err) out.onFail(err) return err }
// publish is used to publish events using the configured protocol client. // It provides general error handling and back off support used on failed // send attempts. To be used by PublishEvent and PublishEvents. // The send callback will try to progress sending traffic and returns kind of // progress made in ok or resetFail. If ok is set to true, send finished // processing events. If ok is false but resetFail is set, send was partially // successful. If send was partially successful, the fail counter is reset thus up // to maxAttempts send attempts without any progress might be executed. func (s *SingleConnectionMode) publish( signaler outputs.Signaler, opts outputs.Options, send func() (ok bool, resetFail bool), ) error { fails := 0 var err error guaranteed := opts.Guaranteed || s.maxAttempts == 0 for !s.closed && (guaranteed || fails < s.maxAttempts) { ok := false resetFail := false if err := s.connect(); err != nil { logp.Info("Connecting error publishing events (retrying): %s", err) goto sendFail } ok, resetFail = send() if !ok { goto sendFail } debug("send completed") s.backoff.Reset() outputs.SignalCompleted(signaler) return nil sendFail: logp.Info("send fail") s.backoff.Wait() fails++ if resetFail { debug("reset fails") fails = 0 } if !guaranteed && (s.maxAttempts > 0 && fails == s.maxAttempts) { // max number of attempts reached debug("max number of attempts reached") break } } debug("messages dropped") messagesDropped.Add(1) outputs.SignalFailed(signaler, err) return nil }
// publish is used to publish events using the configured protocol client. // It provides general error handling and back off support used on failed // send attempts. To be used by PublishEvent and PublishEvents. // The send callback will try to progress sending traffic and returns kind of // progress made in ok or resetFail. If ok is set to true, send finished // processing events. If ok is false but resetFail is set, send was partially // successful. If send was partially successful, the fail counter is reset thus up // to maxAttempts send attempts without any progress might be executed. func (f *FailOverConnectionMode) publish( signaler outputs.Signaler, opts outputs.Options, send func() (ok bool, resetFail bool), ) error { fails := 0 var err error // TODO: we want back off support here? Fail over normally will try another // connection. guaranteed := opts.Guaranteed || f.maxAttempts == 0 for !f.closed && (guaranteed || fails < f.maxAttempts) { ok := false resetFail := false if err = f.connect(f.active); err != nil { logp.Info("Connecting error publishing events (retrying): %s", err) goto sendFail } ok, resetFail = send() if !ok { goto sendFail } debug("send completed") outputs.SignalCompleted(signaler) return nil sendFail: fails++ if resetFail { debug("reset fails") fails = 0 } if !guaranteed && (f.maxAttempts > 0 && fails == f.maxAttempts) { // max number of attempts reached debug("max number of attempts reached") break } time.Sleep(f.waitRetry) } debug("messages dropped") messagesDropped.Add(1) outputs.SignalFailed(signaler, err) return nil }
// publish is used to publish events using the configured protocol client. // It provides general error handling and back off support used on failed // send attempts. To be used by PublishEvent and PublishEvents. // The send callback will try to progress sending traffic and returns kind of // progress made in ok or resetFail. If ok is set to true, send finished // processing events. If ok is false but resetFail is set, send was partially // successful. If send was partially successful, the fail counter is reset thus up // to maxAttempts send attempts without any progress might be executed. func (s *SingleConnectionMode) publish( signaler outputs.Signaler, send func() (ok bool, resetFail bool), ) error { fails := 0 var backoffCount uint var err error for !s.closed && (s.maxAttempts == 0 || fails < s.maxAttempts) { ok := false resetFail := false if err := s.connect(); err != nil { logp.Info("Connecting error publishing events (retrying): %s", err) goto sendFail } ok, resetFail = send() if !ok { goto sendFail } outputs.SignalCompleted(signaler) return nil sendFail: fails++ if resetFail { fails = 0 } if s.maxAttempts > 0 && fails == s.maxAttempts { // max number of attempts reached break } logp.Info("send fail") backoff := time.Duration(int64(s.waitRetry) * (1 << backoffCount)) if backoff > s.maxWaitRetry { backoff = s.maxWaitRetry } else { backoffCount++ } logp.Info("backoff retry: %v", backoff) time.Sleep(backoff) } outputs.SignalFailed(signaler, err) return nil }
// publish is used to publish events using the configured protocol client. // It provides general error handling and back off support used on failed // send attempts. To be used by PublishEvent and PublishEvents. // The send callback will try to progress sending traffic and returns kind of // progress made in ok or resetFail. If ok is set to true, send finished // processing events. If ok is false but resetFail is set, send was partially // successful. If send was partially successful, the fail counter is reset thus up // to maxAttempts send attempts without any progress might be executed. func (f *FailOverConnectionMode) publish( signaler outputs.Signaler, send func() (ok bool, resetFail bool), ) error { fails := 0 var err error // TODO: we want back off support here? Fail over normally will try another // connection. for !f.closed && (f.maxAttempts == 0 || fails < f.maxAttempts) { ok := false resetFail := false if err = f.connect(f.active); err != nil { logp.Info("Connecting error publishing events (retrying): %s", err) goto sendFail } ok, resetFail = send() if !ok { goto sendFail } outputs.SignalCompleted(signaler) return nil sendFail: fails++ if resetFail { fails = 0 } if f.maxAttempts > 0 && fails == f.maxAttempts { // max number of attempts reached break } time.Sleep(f.waitRetry) } outputs.SignalFailed(signaler, err) return nil }
func (c *cmp) PublishEvent( s outputs.Signaler, opts outputs.Options, event common.MapStr, ) error { var err error if err = postToCmp(c, event); err != nil { goto fail } outputs.SignalCompleted(s) return nil fail: if opts.Guaranteed { logp.Critical("Unable to publish events to cmp: %v", err) } outputs.SignalFailed(s, err) return err }
// dropping is called when a message is dropped. It updates the // relevant counters and sends a failed signal. func dropping(msg eventsMessage, ws *common.WorkerSignal) { debug("messages dropped") messagesDropped.Add(1) outputs.SignalFailed(msg.signaler, nil) ws.DoneEvent() }
func stopQueue(qu chan message) { close(qu) for msg := range qu { // clear queue and send fail signal outputs.SignalFailed(msg.context.signal, nil) } }
// dropping is called when a message is dropped. It updates the // relevant counters and sends a failed signal. func dropping(msg eventsMessage) { messagesDropped.Add(1) outputs.SignalFailed(msg.signaler, nil) }
func (m *LoadBalancerMode) onMessage( backoff *backoff, client ProtocolClient, msg eventsMessage, ) (bool, error) { done := false if msg.event != nil { err := client.PublishEvent(msg.event) done = !backoff.WaitOnError(err) if err != nil { if msg.attemptsLeft > 0 { msg.attemptsLeft-- } m.onFail(msg, err) return done, err } } else { events := msg.events total := len(events) for len(events) > 0 { var err error events, err = client.PublishEvents(events) done = !backoff.WaitOnError(err) if done && err != nil { outputs.SignalFailed(msg.signaler, err) return done, err } if err != nil { if msg.attemptsLeft > 0 { msg.attemptsLeft-- } // reset attempt count if subset of messages has been processed if len(events) < total && msg.attemptsLeft >= 0 { debug("reset fails") msg.attemptsLeft = m.maxAttempts } if err != ErrTempBulkFailure { // retry non-published subset of events in batch msg.events = events m.onFail(msg, err) return done, err } if m.maxAttempts > 0 && msg.attemptsLeft == 0 { // no more attempts left => drop dropping(msg) return done, err } // reset total count for temporary failure loop total = len(events) } } } outputs.SignalCompleted(msg.signaler) return done, nil }
func (m *LoadBalancerMode) publishEventsMessage(msg eventsMessage) error { if ok := m.forwardEvent(m.work, msg); !ok { outputs.SignalFailed(msg.signaler, nil) } return nil }