Beispiel #1
0
func (server *serverCodec) WriteResponse(resp *rpc.Response, v interface{}) error {
	body, err := server.codec.codec.Marshal(v)
	if err != nil {
		return err
	}

	server.lock.RLock()
	route, ok := server.calls[resp.Seq]
	server.lock.RUnlock()
	if !ok {
		return errors.New("sequence dosen't have a route")
	}

	publishing := amqp.Publishing{
		ReplyTo:       resp.ServiceMethod,
		MessageId:     route.messageID,
		CorrelationId: route.routing,
		Body:          body,
	}

	if resp.Error != "" {
		publishing.Headers = amqp.Table{"error": resp.Error}
	}

	return server.channel.Publish(
		"",
		route.routing,
		false,
		false,
		publishing,
	)
}
Beispiel #2
0
func PublishFiles(files chan string, connectionUri, exchange,
	routingKey string, mandatory, immediate bool, deliveryProperties DeliveryProperties, results chan *PublishResult) {

	var err error
	var body []byte
	var message *amqp.Publishing
	var messages chan *amqp.Publishing

	messages = make(chan *amqp.Publishing)

	go Publish(messages, connectionUri, exchange, routingKey, mandatory, immediate, results)

	for file := range files {
		if body, err = ioutil.ReadFile(file); err != nil {
			results <- &PublishResult{"Failed to read file " + file, err, false}
			continue
		}

		message = NewAmqpPublishingWithDelivery(deliveryProperties, body)

		if message.ContentType == "" {
			message.ContentType = mime.TypeByExtension(filepath.Ext(file))
		}

		messages <- message
	}
}
Beispiel #3
0
// Publish will send the message to the server to be consumed
func (p *Publisher) Publish(in interface{}) error {
	// Check for close
	if p.channel == nil {
		return ChannelClosed
	}

	// Encode the message
	conf := p.conf
	buf := &p.buf
	buf.Reset()
	if err := conf.Serializer.RelayEncode(buf, in); err != nil {
		return fmt.Errorf("Failed to encode message! Got: %s", err)
	}

	// Format the message
	msg := amqp.Publishing{
		DeliveryMode: p.mode,
		Timestamp:    time.Now().UTC(),
		ContentType:  p.contentType,
		Body:         buf.Bytes(),
	}

	// Check for a message ttl
	if p.conf.MessageTTL > 0 {
		msec := int(p.conf.MessageTTL / time.Millisecond)
		msg.Expiration = strconv.Itoa(msec)
	}

	// Publish the message
	if err := p.channel.Publish(conf.Exchange, p.queue, false, false, msg); err != nil {
		return fmt.Errorf("Failed to publish to '%s'! Got: %s", p.queue, err)
	}

	// Check if we wait for confirmation
	if !p.conf.DisablePublishConfirm {
		select {
		case _, ok := <-p.ackCh:
			if !ok {
				return ChannelClosed
			}
			return nil
		case _, ok := <-p.nackCh:
			if !ok {
				return ChannelClosed
			}
			return fmt.Errorf("Failed to publish to '%s'! Got negative ack.", p.queue)
		case err, ok := <-p.errCh:
			if !ok {
				return ChannelClosed
			}
			log.Printf("[ERR] Publisher got error: (Code %d Server: %v Recoverable: %v) %s",
				err.Code, err.Server, err.Recover, err.Reason)
			return fmt.Errorf("Failed to publish to '%s'! Got: %s", err.Error())
		}
	}
	return nil
}
Beispiel #4
0
func (s *client) send(ch *amqp.Channel, group uint64, o *Options, payload []byte) ([]byte, error) {

	id, err := s.flake.Next()
	if err != nil {
		return nil, err
	}

	groupString := fmt.Sprintf("%d", group)

	envelope := amqp.Publishing{
		MessageId:     fmt.Sprintf("%d", id),
		CorrelationId: groupString,
		Body:          payload,
		DeliveryMode:  amqp.Transient,
		Headers:       amqp.Table{timestampHeader: time.Now().UnixNano()},
	}

	if o.Persistent {
		envelope.DeliveryMode = amqp.Persistent
	}

	mandatory := false
	immediate := false

	if err := ch.Publish(o.Exchange, o.Key, mandatory, immediate, envelope); err != nil {
		return nil, fmt.Errorf("Could not publish to exchange %s: %s", o.Exchange, err)
	}

	h := murmur3.New32()
	h.Write(payload)
	sum := h.Sum(nil)

	size := float32(len(payload)) / 1024

	if len(o.Verbose) > 0 {
		log.Infof("[%d] sending %.2f kB (%x) to %s", id, size, sum, o.Key)
	} else {
		log.Infof("[%d] sending %.2f kB (%x)", id, size, sum)
	}

	return sum, nil
}
Beispiel #5
0
func main() {
	rabbitUrl := os.Getenv("AMQP_URL")

	if rabbitUrl == "" {
		rabbitUrl = "amqp://localhost"
	}

	log.Println(fmt.Sprintf("Connecting to RabbitMQ (%s)", rabbitUrl))

	conn, err := amqp.Dial(rabbitUrl)

	if err != nil {
		panic(err)
	}

	defer conn.Close()

	channel, err := conn.Channel()

	if err != nil {
		panic(err)
	}

	defer channel.Close()

	// The exchange we're going to pull stuff from...
	err = channel.ExchangeDeclare("squall.workers", "fanout", true, false, false, false, nil)

	if err != nil {
		panic(err)
	}

	// The exchange we're going to publish to...
	err = channel.ExchangeDeclare("squall.aggregators", "direct", true, false, false, false, nil)

	if err != nil {
		panic(err)
	}

	// Just ignore this crap.
	_, err = channel.QueueDeclare("", true, false, false, true, nil)

	if err != nil {
		panic(err)
	}

	err = channel.QueueBind("", "#", "squall.workers", true, nil)

	if err != nil {
		panic(err)
	}

	// Start up dat consumer...!
	listener, err := channel.Consume("", "squall.workers", true, false, true, false, nil)

	if err != nil {
		panic(err)
	}

	for {
		select {
		case obj, ok := <-listener:
			{
				Debugln("Found request to execute.")

				if ok {
					request := NewScrapeRequestFromJson(obj.Body)
					log.Printf("Request %d: Starting scrape of %s\n", request.RequestID, request.Url)
					request.PerformAsync(100)
				}
			}
		case resp := <-ResponseQueue:
			{
				Debugln("Read response, sending along.")

				// Do something with this response. Shove it down another pipe?
				message := amqp.Publishing{}
				message.Body = resp.ToJSON()
				message.ContentType = "application/json"

				channel.Publish("squall.aggregators", "", false, false, message)
			}
		}
	}
}