Push error messages to error topic when NATS mqtrigger fail (#724)

This commit is contained in:
Nafisa Shazia
2018-06-27 00:27:57 +08:00
committed by Ta-Ching Chen
parent 71d8b769d5
commit 1ed59f0789
6 changed files with 155 additions and 21 deletions
+47 -14
View File
@@ -107,35 +107,67 @@ func msgHandler(nats *Nats, trigger *crd.MessageQueueTrigger) func(*ns.Msg) {
log.Printf("Making HTTP request to %v", url)
headers := map[string]string{
"X-Fission-MQTrigger-Topic": trigger.Spec.Topic,
"X-Fission-MQTrigger-RespTopic": trigger.Spec.ResponseTopic,
"Content-Type": trigger.Spec.ContentType,
"X-Fission-MQTrigger-Topic": trigger.Spec.Topic,
"X-Fission-MQTrigger-RespTopic": trigger.Spec.ResponseTopic,
"X-Fission-MQTrigger-ErrorTopic": trigger.Spec.ErrorTopic,
"Content-Type": trigger.Spec.ContentType,
}
// Create request
req, err := http.NewRequest("POST", url, bytes.NewReader(msg.Data))
if err != nil {
log.Errorf("Could not issue POST request with message to url %v", url)
return
}
for k, v := range headers {
req.Header.Add(k, v)
}
// Make the request
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Warningf("Request failed: %v", url)
var resp *http.Response
for attempt := 0; attempt <= trigger.Spec.MaxRetries; attempt++ {
// Make the request
resp, err = http.DefaultClient.Do(req)
if err != nil {
log.Error("Error invoking function for trigger %v: %v", trigger.Metadata.Name, err)
continue
}
if resp == nil {
continue
}
if err == nil && resp.StatusCode == http.StatusOK {
// Success, quit retrying
break
}
}
if resp == nil {
log.Warning("Every retry failed; final retry gave empty response.")
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Warningf("Request body error: %v", string(body))
body, bodyErr := ioutil.ReadAll(resp.Body)
if bodyErr != nil {
log.Warningf("Response body error: %v", bodyErr)
return
}
if resp.StatusCode != 200 {
log.Printf("Request returned failure: %v", resp.StatusCode)
return
// Only the latest error response will be published to error topic
if err != nil || resp.StatusCode != 200 {
if len(trigger.Spec.ErrorTopic) > 0 && len(body) > 0 {
publishErr := nats.nsConn.Publish(trigger.Spec.ErrorTopic, body)
if publishErr != nil {
log.Error("Failed to publish error to error topic: %v", publishErr)
// TODO: We will ack this message after max retries to prevent re-processing but
// this may cause message loss
}
}
}
// trigger acks message only if a request done successfully
// Trigger acks message only if a request was processed successfully
err = msg.Ack()
if err != nil {
log.Warningf("Failed to ack message: %v", err)
@@ -148,4 +180,5 @@ func msgHandler(nats *Nats, trigger *crd.MessageQueueTrigger) func(*ns.Msg) {
}
}
}
}