func main() { flag.Parse() showUsageAndStatus() // Construct new client with the flag url // and default backoff policy cli := cony.NewClient( cony.URL(*url), cony.Backoff(cony.DefaultBackoff), ) // Declarations // The queue name will be supplied by the AMQP server que := &cony.Queue{ AutoDelete: true, Name: "myQueue", } exc := cony.Exchange{ Name: "myExc", Kind: "fanout", AutoDelete: true, } bnd := cony.Binding{ Queue: que, Exchange: exc, Key: "pubSub", } cli.Declare([]cony.Declaration{ cony.DeclareQueue(que), cony.DeclareExchange(exc), cony.DeclareBinding(bnd), }) // Declare and register a consumer cns := cony.NewConsumer( que, cony.AutoAck(), // Auto sign the deliveries ) cli.Consume(cns) for cli.Loop() { select { case msg := <-cns.Deliveries(): log.Printf("Received body: %q\n", msg.Body) // If when we built the consumer we didn't use // the "cony.AutoAck()" option this is where we'd // have to call the "amqp.Deliveries" methods "Ack", // "Nack", "Reject" // // msg.Ack(false) // msg.Nack(false) // msg.Reject(false) case err := <-cns.Errors(): fmt.Printf("Consumer error: %v\n", err) case err := <-cli.Errors(): fmt.Printf("Client error: %v\n", err) } } }
func main() { flag.Parse() showUsageAndStatus() // Construct new client with the flag url // and default backoff policy cli := cony.NewClient( cony.URL(*url), cony.Backoff(cony.DefaultBackoff), ) // Declare the exchange we'll be using exc := cony.Exchange{ Name: "myExc", Kind: "fanout", AutoDelete: true, } cli.Declare([]cony.Declaration{ cony.DeclareExchange(exc), }) // Declare and register a publisher // with the cony client pbl := cony.NewPublisher(exc.Name, "pubSub") cli.Publish(pbl) // Launch a go routine and publish a message. // "Publish" is a blocking method this is why it // needs to be called in its own go routine. // go func() { ticker := time.NewTicker(time.Second) for { select { case <-ticker.C: fmt.Printf("Client publishing\n") err := pbl.Publish(amqp.Publishing{ Body: []byte(*body), }) if err != nil { fmt.Printf("Client publish error: %v\n", err) } } } }() // Client loop sends out declarations(exchanges, queues, bindings // etc) to the AMQP server. It also handles reconnecting. for cli.Loop() { select { case err := <-cli.Errors(): fmt.Printf("Client error: %v\n", err) case blocked := <-cli.Blocking(): fmt.Printf("Client is blocked %v\n", blocked) } } }
func ExampleClient_Loop() { client := cony.NewClient(cony.URL("amqp://*****:*****@localhost/")) for client.Loop() { select { case err := <-client.Errors(): log.Println("CLIENT ERROR: ", err) client.Close() } time.Sleep(1 * time.Second) // naive backoff } }
func main() { flag.Parse() showUsageAndStatus() // Construct new client with the flag url // and default backoff policy cli := cony.NewClient( cony.URL(*url), cony.Backoff(cony.DefaultBackoff), ) // Declare the exchange we'll be using exc := cony.Exchange{ Name: "web", Kind: "fanout", AutoDelete: true, } cli.Declare([]cony.Declaration{ cony.DeclareExchange(exc), }) // Declare and register a publisher // with the cony client. // This needs to be "global" per client // and we'll need to use this exact value in // our handlers (contexts should be of help) pbl := cony.NewPublisher(exc.Name, "") cli.Publish(pbl) // Start our loop in a new gorouting // so we don't block this one go func() { for cli.Loop() { select { case err := <-cli.Errors(): fmt.Println(err) } } }() // Simple template for our web-view tpl, err := template.New("form").Parse(form) if err != nil { log.Fatal(err) return } // HTTP handler function http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { // "GET" shows the template along // with the possible thanks message hdr := w.Header() hdr["Content-Type"] = []string{"text/html"} tpl.Execute(w, map[string]string{ "status": r.FormValue("status"), }) return } else if r.Method == "POST" { // "POST" publishes the value received // from the form to AMQP // Note: we're using the "pbl" variable // (declared above in our code) and we // don't declare a new Publisher value. go pbl.Publish(amqp.Publishing{ Body: []byte(r.FormValue("body")), }) http.Redirect(w, r, "/?status=thanks", http.StatusFound) return } http.Error(w, "404 not found", http.StatusNotFound) }) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%v", *port), nil)) }
func ExampleURL() { cony.NewClient(cony.URL("amqp://*****:*****@localhost/")) }
func Example() { client := cony.NewClient(cony.URL(os.Getenv("AMQP_URL")), cony.Backoff(cony.DefaultBackoff)) q := &cony.Queue{ Name: "", // autogenerated queue name AutoDelete: true, } exchange := cony.Exchange{ Name: "amq.topic", Durable: true, } b := cony.Binding{ Queue: q, Exchange: exchange, Key: "something.#", } // wrap all declarations and save into slice declarations := []cony.Declaration{ cony.DeclareQueue(q), cony.DeclareExchange(exchange), cony.DeclareBinding(b), } // declare consumer consumer := cony.NewConsumer(q, cony.Qos(10), cony.AutoTag(), cony.AutoAck(), ) // declare publisher publisher := cony.NewPublisher(exchange.Name, "ololo.key", cony.PublishingTemplate(amqp.Publishing{ ContentType: "application/json", AppId: "app1", }), // template amqp.Publising ) // let client know about declarations client.Declare(declarations) // let client know about consumers/publishers client.Consume(consumer) client.Publish(publisher) clientErrs := client.Errors() deliveries := consumer.Deliveries() consumerErrs := consumer.Errors() // connect, reconnect, or exit loop // run network operations such as: // queue, exchange, bidning, consumers declarations for client.Loop() { select { case msg := <-deliveries: log.Println(msg) msg.Ack(false) publisher.Write([]byte("ololo reply")) case err := <-consumerErrs: log.Println("CONSUMER ERROR: ", err) case err := <-clientErrs: log.Println("CLIENT ERROR: ", err) client.Close() } } }
func main() { flag.Parse() showUsageAndStatus() // Channel used for stopping goroutines done := make(chan struct{}) // Items channel used for sending our delivieries to the workers itms := make(chan item) // Construct new client with the flag url // and default backoff policy cli := cony.NewClient( cony.URL(*url), cony.Backoff(cony.DefaultBackoff), ) // Declarations // The queue name will be supplied by the AMQP server que := &cony.Queue{ AutoDelete: true, } exc := cony.Exchange{ Name: "email", Kind: "fanout", AutoDelete: true, } bnd := cony.Binding{ Queue: que, Exchange: exc, Key: "", } cli.Declare([]cony.Declaration{ cony.DeclareQueue(que), cony.DeclareExchange(exc), cony.DeclareBinding(bnd), }) // Declare and register a consumer cns := cony.NewConsumer( que, ) cli.Consume(cns) // Go routing that uses the cony loop to receive delivieris // handle reconnects, etc // We use the done channel to exit from this goroutine. go func() { for cli.Loop() { select { case msg := <-cns.Deliveries(): var ipt map[string]string err := json.Unmarshal(msg.Body, &ipt) if err != nil { msg.Reject(false) } log.Printf("Received body: %q\n", msg.Body) // If when we built the consumer we didn't use // the "cony.AutoAck()" option this is where we'd // have to call the "amqp.Deliveries" methods "Ack", // "Nack", "Reject" // // msg.Ack(false) // msg.Nack(false) // msg.Reject(false) itms <- item{ ipt: ipt, ack: msg.Ack, nack: msg.Nack, } case err := <-cns.Errors(): fmt.Printf("Consumer error: %v\n", err) case err := <-cli.Errors(): fmt.Printf("Client error: %v\n", err) case <-done: return } } }() // Workers go func() { num := 3 for i := 0; i < num; i++ { go func() { for { select { case itm := <-itms: err := sendMail(itm.ipt) if err != nil { fmt.Println(err) } itm.ack(false) case <-done: return } } }() } }() // Block this indefinitely <-done }