Example #1
0
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)
		}
	}
}
Example #2
0
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)
		}
	}
}
Example #3
0
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))
}
Example #4
0
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()
		}
	}

}
Example #5
0
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
}