# Ruby with RabbitMQ and LavinMQ

We recommend [amqp-client.rb](https://github.com/cloudamqp/amqp-client.rb). It reconnects automatically, recovers your consumers after a reconnect, and has no dependencies.

```bash
gem install amqp-client
```

## Publish and consume

Set `BROKER_URL` to the AMQP URL from your instance’s details page in the CloudAMQP console. Without it, the examples connect to a local broker.

Save the connection helper as `amqp.rb`:

```ruby
require "amqp-client"

module Amqp
  def self.client
    AMQP::Client.new(ENV.fetch("BROKER_URL", "amqp://guest:guest@localhost")).start
  end
end
```

Save the publisher as `publisher.rb`:

```ruby
require_relative "amqp"

module Publisher
  # Messages are persistent and wait for a publisher confirm by default
  def self.publish(client, queue, message)
    client.queue(queue).publish(message)
    puts " [x] Sent #{message.inspect}"
  end
end

if __FILE__ == $PROGRAM_NAME
  client = Amqp.client
  Publisher.publish(client, "hello", "Hello world!")
  client.stop
end
```

Save the consumer as `worker.rb` in the same directory:

```ruby
require_relative "amqp"

module Worker
  # The message is acked when the block returns, and requeued if it raises
  def self.consume(client, queue, &handler)
    client.queue(queue).subscribe(prefetch: 10) do |msg|
      handler.call(msg.body)
    end
  end
end

if __FILE__ == $PROGRAM_NAME
  client = Amqp.client
  Worker.consume(client, "hello") { |message| puts " [x] Received #{message.inspect}" }
  puts " [*] Waiting for messages. To exit press CTRL+C"
  begin
    sleep
  rescue Interrupt
    client.stop
  end
end
```

Run `ruby worker.rb` in one terminal and `ruby publisher.rb` in another.

A runnable example is in [ruby/amqp-client in cloudamqp/examples](https://github.com/cloudamqp/examples/tree/main/ruby/amqp-client).

## Good to know

- **Connect with the URL.** `AMQP::Client.new(url).start`, where the URL is the one on your instance’s details page in the CloudAMQP console.
- **Messages are safe by default.** `publish` sends persistent messages and waits until the broker has confirmed them.
- **Messages are acked after your block returns.** If the block raises, the message is requeued. Make your handler idempotent, because a message can be delivered again after a reconnect.
- **Set a prefetch limit** when you subscribe, e.g. `subscribe(prefetch: 10)`, so a consumer doesn’t buffer more messages than it can handle.
- **Use `amqps://`** to connect over TLS. The server certificate is verified.

See the [amqp-client.rb README](https://github.com/cloudamqp/amqp-client.rb#readme) for codecs, RPC and the low-level API.

## Other Ruby libraries

- [Bunny](https://github.com/ruby-amqp/bunny), a widely used synchronous client
- [March Hare](https://github.com/ruby-amqp/march_hare), for JRuby, built on the RabbitMQ Java client
- [Kicks](https://github.com/ruby-amqp/kicks) (formerly Sneakers), a background job framework
- [Hutch](https://github.com/ruby-amqp/hutch), for inter-service communication

## Video tutorial
https://www.youtube.com/embed/i6_4J3fZxVE
