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, ) }
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 } }
// 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 }
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 }
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) } } } }