Example #1
0
func (c *Consumer) listenForMessages(conn *connection, callback func(*events.Envelope)) error {
	if conn.closed() {
		return nil
	}
	ws := conn.websocket()
	for {
		if c.idleTimeout != 0 {
			ws.SetReadDeadline(time.Now().Add(c.idleTimeout))
		}
		_, data, err := ws.ReadMessage()

		// If the connection was closed (i.e. if conn.Close() was called), we
		// will have a non-nil error, but we want to return a nil error.
		if conn.closed() {
			return nil
		}

		if c.isTimeoutErr(err) {
			return noaa_errors.NewRetryError(err)
		}

		if err != nil {
			return err
		}

		envelope := &events.Envelope{}
		err = proto.Unmarshal(data, envelope)
		if err != nil {
			continue
		}

		callback(envelope)
	}
}
Example #2
0
func (c *Consumer) retryAction(action func() (err error, done bool), errors chan<- error) {
	oldConnectCallback := c.onConnectCallback()
	defer c.SetOnConnectCallback(oldConnectCallback)
	nextSleep := atomic.LoadInt64(&c.minRetryDelay)

	c.SetOnConnectCallback(func() {
		atomic.StoreInt64(&nextSleep, atomic.LoadInt64(&c.minRetryDelay))
		if oldConnectCallback != nil {
			oldConnectCallback()
		}
	})

	for {
		err, done := action()
		if done {
			return
		}

		if _, ok := err.(noaa_errors.NonRetryError); ok {
			c.debugPrinter.Print("WEBSOCKET ERROR", fmt.Sprintf("%s. Retrying...", err.Error()))
			errors <- err
			return
		}

		if err != nil {
			c.debugPrinter.Print("WEBSOCKET ERROR", fmt.Sprintf("%s. Retrying...", err.Error()))
			err = noaa_errors.NewRetryError(err)
		}

		errors <- err

		ns := atomic.LoadInt64(&nextSleep)
		time.Sleep(time.Duration(ns))
		ns = atomic.AddInt64(&nextSleep, ns)
		max := atomic.LoadInt64(&c.maxRetryDelay)
		if ns > max {
			atomic.StoreInt64(&nextSleep, max)
		}
	}
}
				var wg sync.WaitGroup
				wg.Add(1)
				defer wg.Wait()
				go func() {
					defer wg.Done()
					repo.TailLogsFor("app-guid", func() {}, logChan, errChan)
				}()

				Eventually(errChan).Should(Receive(&err))

				close(done)
			})

			It("does not return a RetryError before RetryTimeout", func(done Done) {
				defer repo.Close()
				err := noaaerrors.NewRetryError(errors.New("oops"))

				fakeNoaaConsumer.TailingLogsStub = func(appGuid string, authToken string) (<-chan *events.LogMessage, <-chan error) {
					e <- err
					return c, e
				}

				var wg sync.WaitGroup
				wg.Add(1)
				defer wg.Wait()
				go func() {
					defer wg.Done()
					repo.TailLogsFor("app-guid", func() {}, logChan, errChan)
				}()

				Consistently(errChan).ShouldNot(Receive())