// Message decodes the message containined in a delivery. // Will return an error if delivery.HasMessage() is false. func (delivery Delivery) Message() (m amqp.Message, err error) { if !delivery.Readable() || delivery.Partial() { return nil, internal.Errorf("attempting to get incomplete message") } data := make([]byte, delivery.Pending()) result := delivery.Link().Recv(data) if result != len(data) { return nil, internal.Errorf("cannot receive message: %s", internal.PnErrorCode(result)) } m = amqp.NewMessage() err = m.Decode(data) return }
func main() { flag.Usage = usage flag.Parse() urls := flag.Args() // Non-flag arguments are URLs to receive from if len(urls) == 0 { log.Println("No URL provided") flag.Usage() os.Exit(1) } sentChan := make(chan sent) // Channel to receive all the delivery receipts. var wait sync.WaitGroup // Used by main() to wait for all goroutines to end. wait.Add(len(urls)) // Wait for one goroutine per URL. container := concurrent.NewContainer("") var connections []concurrent.Connection // Store connctions to close on exit // Start a goroutine for each URL to send messages. for _, urlStr := range urls { util.Debugf("Connecting to %v\n", urlStr) go func(urlStr string) { defer wait.Done() // Notify main() that this goroutine is done. url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults. util.ExitIf(err) // Open a new connection conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port" util.ExitIf(err) c, err := container.NewConnection(conn) util.ExitIf(err) err = c.Open() util.ExitIf(err) connections = append(connections, c) // Save connection so it will be closed when main() ends // Create and open a session ss, err := c.NewSession() util.ExitIf(err) err = ss.Open() util.ExitIf(err) // Create a Sender using the path of the URL as the AMQP address s, err := ss.Sender(url.Path) util.ExitIf(err) // Loop sending messages. for i := int64(0); i < *count; i++ { m := amqp.NewMessage() body := fmt.Sprintf("%v-%v", url.Path, i) m.Marshal(body) sentMessage, err := s.Send(m) util.ExitIf(err) sentChan <- sent{body, sentMessage} } }(urlStr) } // Wait for all the acknowledgements expect := int(*count) * len(urls) util.Debugf("Started senders, expect %v acknowledgements\n", expect) for i := 0; i < expect; i++ { d := <-sentChan disposition, err := d.sentMessage.Disposition() if err != nil { util.Debugf("acknowledgement[%v] %v error: %v\n", i, d.name, err) } else { util.Debugf("acknowledgement[%v] %v (%v)\n", i, d.name, disposition) } } fmt.Printf("Received all %v acknowledgements\n", expect) wait.Wait() // Wait for all goroutines to finish. for _, c := range connections { // Close all connections if c != nil { c.Close(nil) } } }