
The current idiom forever := make(chan bool) gives the impression that booleans will be sent through `forever`. But the channel never has anything sent through it; its purpose is just to block indefinitely. Go doesn't have any bottom type (empty type; ⊥), but it does have a unit type, namely `struct{}`. Because not even such values will be sent, the channel need not even exist at all, leaving no doubts as to its purpose.
70 lines
1.4 KiB
Go
70 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"log"
|
|
"time"
|
|
|
|
amqp "github.com/rabbitmq/amqp091-go"
|
|
)
|
|
|
|
func failOnError(err error, msg string) {
|
|
if err != nil {
|
|
log.Panicf("%s: %s", msg, err)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
|
|
failOnError(err, "Failed to connect to RabbitMQ")
|
|
defer conn.Close()
|
|
|
|
ch, err := conn.Channel()
|
|
failOnError(err, "Failed to open a channel")
|
|
defer ch.Close()
|
|
|
|
q, err := ch.QueueDeclare(
|
|
"task_queue", // name
|
|
true, // durable
|
|
false, // delete when unused
|
|
false, // exclusive
|
|
false, // no-wait
|
|
nil, // arguments
|
|
)
|
|
failOnError(err, "Failed to declare a queue")
|
|
|
|
err = ch.Qos(
|
|
1, // prefetch count
|
|
0, // prefetch size
|
|
false, // global
|
|
)
|
|
failOnError(err, "Failed to set QoS")
|
|
|
|
msgs, err := ch.Consume(
|
|
q.Name, // queue
|
|
"", // consumer
|
|
false, // auto-ack
|
|
false, // exclusive
|
|
false, // no-local
|
|
false, // no-wait
|
|
nil, // args
|
|
)
|
|
failOnError(err, "Failed to register a consumer")
|
|
|
|
var forever chan struct{}
|
|
|
|
go func() {
|
|
for d := range msgs {
|
|
log.Printf("Received a message: %s", d.Body)
|
|
dotCount := bytes.Count(d.Body, []byte("."))
|
|
t := time.Duration(dotCount)
|
|
time.Sleep(t * time.Second)
|
|
log.Printf("Done")
|
|
d.Ack(false)
|
|
}
|
|
}()
|
|
|
|
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
|
|
<-forever
|
|
}
|