func (p *MNSWriter) Write(data []byte) (n int, err error) { resource := fmt.Sprintf("queues/%s/%s", p.conf.Queue, "messages") reqData := ali_mns.MessageSendRequest{ MessageBody: ali_mns.Base64Bytes(data), DelaySeconds: int64(p.conf.DelaySeconds), Priority: int64(p.conf.Priority), } var resp *http.Response if resp, err = p.client.Send(ali_mns.POST, nil, reqData, resource); err != nil { return } if resp != nil { defer resp.Body.Close() if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent { err = ErrMNSWriteMessageError if body, e := ioutil.ReadAll(resp.Body); e == nil { spirit.Logger().WithField("actor", spirit.ActorWriter). WithField("urn", msnWriterURN). WithField("event", "write"). WithField("url", p.conf.URL). WithField("queue", p.conf.Queue). WithField("status_code", resp.StatusCode). WithField("response", string(body)). Debugln(err) } return } } return }
func (p *MNSSender) callFlow(delivery spirit.Delivery, flowMetadata *MNSFlowMetadata) { if flowMetadata == nil { return } sendDeliveryFunc := func(ignoreSendError bool, delivery spirit.Delivery, queueURN map[string]string, queues ...string) (err error) { if queues == nil || len(queues) == 0 { return } backupURN := delivery.URN() backupParallel := new(MNSParallelFlowMetadata) delivery.Payload().Context().Object(mnsSenderQueueParallelIdContext, backupParallel) // recover defer func() { delivery.SetURN(backupURN) delivery.Payload().SetContext(mnsSenderQueueParallelIdContext, backupParallel) }() for _, q := range queues { if q == "" { continue } parallelQueues := strings.Split(q, "||") parallelCount := len(parallelQueues) parallelQueuePid := "" if parallelCount > 0 { parallelQueuePid = xid.New().String() } for index, queue := range parallelQueues { // recover delivery.SetURN(backupURN) delivery.Payload().SetContext(mnsSenderQueueParallelIdContext, backupParallel) urn := "" if queueURN != nil { urn, _ = queueURN[queue] } buf := bytes.Buffer{} delivery.SetURN(urn) if parallelCount > 0 { delivery.Payload().SetContext(mnsSenderQueueParallelIdContext, MNSParallelFlowMetadata{Id: parallelQueuePid, Index: index, Count: parallelCount}) } if err = p.translator.Out(&buf, delivery); err != nil { spirit.Logger(). WithField("actor", spirit.ActorSender). WithField("urn", mnsSenderURN). WithField("event", "translate delivery"). Errorln(err) return } else { reqData := ali_mns.MessageSendRequest{ MessageBody: ali_mns.Base64Bytes(buf.Bytes()), DelaySeconds: int64(p.conf.DelaySeconds), Priority: int64(p.conf.Priority), } client := p.getMNSClient(queue) if _, err = client.SendMessage(reqData); err != nil { spirit.Logger(). WithField("actor", spirit.ActorSender). WithField("urn", mnsSenderURN). WithField("event", "send mns message"). Errorln(err) if ignoreSendError { err = nil continue } return } } } } return } currentQueueURN := map[string]string{} if err := delivery.Metadata().Object(mnsSenderQueueURNMetadata, ¤tQueueURN); err != nil { spirit.Logger(). WithField("actor", spirit.ActorSender). WithField("urn", mnsSenderURN). WithField("event", "get queue urn"). Errorln(err) } if delivery.Payload().LastError() != nil { // run error flow if flowMetadata.Error != nil && len(flowMetadata.Error) > 0 { queueURN := map[string]string{} for _, queue := range flowMetadata.Error { if urn, exist := currentQueueURN[queue]; exist { queueURN[queue] = urn } } delivery.SetMetadata(mnsSenderFlowMetadata, nil) sendDeliveryFunc(true, delivery, queueURN, flowMetadata.Error...) } } else { // run normal flow if flowMetadata.Normal != nil && len(flowMetadata.Normal) > 0 { nextQueue := flowMetadata.Normal[flowMetadata.CurrentFlowId] queueURN := map[string]string{} if len(flowMetadata.Normal) > flowMetadata.CurrentFlowId { tmpRemainQueues := flowMetadata.Normal[flowMetadata.CurrentFlowId:] remainQueues := []string{} for _, queue := range tmpRemainQueues { queues := strings.Split(queue, "||") remainQueues = append(remainQueues, queues...) } for _, queue := range remainQueues { if urn, exist := currentQueueURN[queue]; exist { queueURN[queue] = urn } } } flowMetadata.CurrentFlowId += 1 defer func() { flowMetadata.CurrentFlowId -= 1 }() delivery.SetMetadata(mnsSenderFlowMetadata, flowMetadata) sendDeliveryFunc(false, delivery, queueURN, nextQueue) } } }