GithubHelp home page GithubHelp logo

timcharper / akka-rabbitmq Goto Github PK

View Code? Open in Web Editor NEW

This project forked from shellrechargesolutionseu/akka-rabbitmq

0.0 1.0 0.0 125 KB

RabbitMq client in Scala and Akka actors

License: Other

Scala 100.00%

akka-rabbitmq's Introduction

Akka RabbitMQ client Build Status

This small library allows you use RabbitMQ client via Akka Actors. The main idea implemented in library is to survive losing connection with RabbitMQ server

It gives you two actors ConnectionActor and ChannelActor

ConnectionActor

  • handles connection failures and notifies children
  • keep trying to reconnect if connection lost
  • provides children with new channels when needed

ChannelActor

  • may store messages in memory if channel lost
  • send stored messages as soon as new channel received
  • retrieve new channel if current is broken

Please note that while this library transparently reconnects when a connection fails, it cannot guarantee that no messages will be lost. If you want to make sure every message is delivered, look into you have to use acknowledgements and confirms. This is documented in the RabbitMQ Reliability Guide. An example program using confirms is included as ConfirmsExample.scala.

Setup

Sbt

resolvers += "The New Motion Public Repo" at "http://nexus.thenewmotion.com/content/groups/public/"
libraryDependencies += "com.thenewmotion.akka" %% "akka-rabbitmq" % "1.2.4"

Maven

<repository>
    <id>thenewmotion</id>
    <name>The New Motion Repository</name>
    <url>http://nexus.thenewmotion.com/content/groups/public/</url>
</repository>
...
<dependency>
    <groupId>com.thenewmotion.akka</groupId>
    <artifactId>akka-rabbitmq_{2.10/2.11}</artifactId>
    <version>1.2.4</version>
</dependency>

Tutorial in comparisons

Before start, you need to add import statement

    import com.thenewmotion.akka.rabbitmq._

Create connection

Default approach:

    val factory = new ConnectionFactory()
    val connection: Connection = factory.newConnection()

Actor style:

    val factory = new ConnectionFactory()
    val connectionActor: ActorRef = system.actorOf(ConnectionActor.props(factory))

Let's name it:

    system.actorOf(ConnectionActor.props(factory), "my-connection")

How often will it reconnect?

    import concurrent.duration._
    system.actorOf(ConnectionActor.props(factory, reconnectionDelay = 10.seconds), "my-connection")

Create channel

That's plain option:

    val channel: Channel = connection.createChannel()

But we can do better. Asynchronously:

    connectionActor ! CreateChannel(ChannelActor.props())

Synchronously:

    import com.thenewmotion.akka.rabbitmq.reachConnectionActor

    val channelActor: ActorRef = connectionActor.createChannel(ChannelActor.props())

Maybe give it a name:

    connectionActor.createChannel(ChannelActor.props(), Some("my-channel"))

What's about custom actor:

    connectionActor.createChannel(Props(new Actor {
      def receive = {
        case channel: Channel =>
      }
    }))

Setup channel

    channel.queueDeclare("queue_name", false, false, false, null)

Actor style:

    // this function will be called each time new channel received
    def setupChannel(channel: Channel, self: ActorRef) {
      channel.queueDeclare("queue_name", false, false, false, null)
    }
    val channelActor: ActorRef = connectionActor.createChannel(ChannelActor.props(setupChannel))

Use channel

    channel.basicPublish("", "queue_name", null, "Hello world".getBytes)

Using our channelActor:

    def publish(channel: Channel) {
      channel.basicPublish("", "queue_name", null, "Hello world".getBytes)
    }
    channelActor ! ChannelMessage(publish)

But I don't want to lose messages when connection is lost:

    channelActor ! ChannelMessage(publish, dropIfNoChannel = false)

Close channel

    channel.close()

VS

    system stop channelActor

Close connection

    connection.close()

VS

    system stop connectionActor // will close all channels associated with this connection

You can shutdown ActorSystem, this will close all connections as well as channels:

    system.shutdown()

Examples:

Publish/Subscribe

Here is RabbitMQ Publish/Subscribe in actors style

object PublishSubscribe extends App {
  implicit val system = ActorSystem()
  val factory = new ConnectionFactory()
  val connection = system.actorOf(ConnectionActor.props(factory), "rabbitmq")
  val exchange = "amq.fanout"


  def setupPublisher(channel: Channel, self: ActorRef) {
    val queue = channel.queueDeclare().getQueue
    channel.queueBind(queue, exchange, "")
  }
  connection ! CreateChannel(ChannelActor.props(setupPublisher), Some("publisher"))


  def setupSubscriber(channel: Channel, self: ActorRef) {
    val queue = channel.queueDeclare().getQueue
    channel.queueBind(queue, exchange, "")
    val consumer = new DefaultConsumer(channel) {
      override def handleDelivery(consumerTag: String, envelope: Envelope, properties: BasicProperties, body: Array[Byte]) {
        println("received: " + fromBytes(body))
      }
    }
    channel.basicConsume(queue, true, consumer)
  }
  connection ! CreateChannel(ChannelActor.props(setupSubscriber), Some("subscriber"))


  Future {
    def loop(n: Long) {
      val publisher = system.actorFor("/user/rabbitmq/publisher")

      def publish(channel: Channel) {
        channel.basicPublish(exchange, "", null, toBytes(n))
      }
      publisher ! ChannelMessage(publish, dropIfNoChannel = false)

      Thread.sleep(1000)
      loop(n + 1)
    }
    loop(0)
  }

  def fromBytes(x: Array[Byte]) = new String(x, "UTF-8")
  def toBytes(x: Long) = x.toString.getBytes("UTF-8")
}

akka-rabbitmq's People

Contributors

mateuszjaje avatar plokhotnyuk avatar romansky avatar t3hnar avatar timcharper avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.