Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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, &currentQueueURN); 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)
		}
	}
}