func (fh *ForwardHandler) Handle(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil || len(body) == 0 { w.WriteHeader(500) fmt.Fprintln(w, "could not read request body") return } eventType, err := events.EventType(body) if err != nil { w.WriteHeader(500) fmt.Fprintln(w, err.Error()) return } switch eventType { case "api_post_event", "deployment_info": log.WithField("eventType", eventType).Info("handling event") fh.HandleAppEvent(w, body) case "app_terminated_event": log.WithField("eventType", "app_terminated_event").Info("handling event") fh.HandleTerminationEvent(w, body) case "status_update_event": log.WithField("eventType", "status_update_event").Info("handling event") fh.HandleStatusEvent(w, body) default: log.WithField("eventType", eventType).Info("not handling event") w.WriteHeader(200) fmt.Fprintf(w, "cannot handle %s\n", eventType) } log.Debug(string(body)) }
func SubscribeToEventStream(config *config.Config, m marathon.Marathon, fh *ForwardHandler) { Reconnect: for { resp, err := makeEventStreamRequest(m.Url("/v2/events")) defer resp.Body.Close() reader := bufio.NewReader(resp.Body) log.Info("connected to /v2/events endpoint") if err != nil { log.WithError(err).Error("error connecting to event stream!") time.Sleep(10 * time.Second) log.Info("reconnecting...") continue Reconnect } for { body, err := reader.ReadBytes('\n') if err != nil { log.WithError(err).Error("error reading from event stream!") time.Sleep(10 * time.Second) log.Info("reconnecting...") continue Reconnect } // marathon sends blank lines to keep the connection alive if bytes.Equal(body, []byte{'\r', '\n'}) { continue } // we don't care about these headers, since the data blob has an // "eventType" field if string(body[0:6]) == "event:" { continue } if string(body[0:5]) == "data:" { body = body[6:] eventType, err := events.EventType(body) if err != nil { log.WithError(err).Error("error parsing event") continue } eventLogger := log.WithField("eventType", eventType) switch eventType { case "api_post_event", "deployment_info": eventLogger.Info("handling event") err = fh.HandleAppEvent(body) case "app_terminated_event": eventLogger.Info("handling event") err = fh.HandleTerminationEvent(body) case "status_update_event": eventLogger.Info("handling event") err = fh.HandleStatusEvent(body) default: eventLogger.Info("not handling event") } if err != nil { eventLogger.WithError(err).Error("body generated error") continue } } } } }