title: Pubsub using Topic Groups with Akka Cluster
body: <p>I'm trying to create a pubsub-style application with Akka Cluster. I'm reading <a href="http://doc.akka.io/docs/akka/2.4/scala/distributed-pub-sub.html#Publish" rel="nofollow noreferrer">the docs</a> about pubsub and am trying to now run their example.</p>
  
  <p>My basic workflow is this:</p>
  
  <p>Run the subscriber (who becomes the master/leader).
  Run the publisher (who will send a string to the topic. All subscribers will receive this message).</p>
  
  <p>Here's my code:</p>
  
  <h3><code>Subscriber.scala</code></h3>
  
  <pre><code>import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
  import akka.cluster.pubsub.{DistributedPubSub, DistributedPubSubMediator}
  
  class Subscriber extends Actor with ActorLogging {
    import DistributedPubSubMediator.{ Subscribe, SubscribeAck }
    val mediator = DistributedPubSub(context.system).mediator
    // subscribe to the topic named "content"
    mediator ! Subscribe("content", self)
  
    def receive = {
      case s: String =&gt;
        log.info("Got {}", s)
      case SubscribeAck(Subscribe("content", None, `self`)) =&gt;
        log.info("subscribing");
    }
  }
  
  object SubscriberMain extends App {
    val system = ActorSystem("ClusterSystem")
    val actor = system.actorOf(Props[Subscriber], name="Subscriber")
  }
  </code></pre>
  
  <h3><code>Publisher.scala</code></h3>
  
  <pre><code>import akka.actor.{Actor, ActorSystem, Props}
  import akka.cluster.pubsub.{DistributedPubSub, DistributedPubSubMediator}
  import com.typesafe.config.ConfigFactory
  
  class Publisher extends Actor {
    import DistributedPubSubMediator.Publish
    // activate the extension
    val mediator = DistributedPubSub(context.system).mediator
  
    def receive = {
      case in: String =&gt; {
        val out = in.toUpperCase
        println(s"Received '$in', transformed to '$out'.")
        mediator ! Publish("content", out)
      }
    }
  }
  
  object PublisherMain extends App {
    val config = ConfigFactory.load()
    val system = ActorSystem("ClusterSystem", config.getConfig("PublishApp"))
    val actor = system.actorOf(Props[Publisher], name="Publisher")
    actor ! "something small"
  }
  </code></pre>
  
  <h3><code>application.conf</code></h3>
  
  <pre><code>akka {
    loglevel = "INFO"
    actor {
      provider = "akka.cluster.ClusterActorRefProvider"
    }
    remote {
      log-remote-lifecycle-events = off
      netty.tcp {
        hostname = "127.0.0.1"
        port = 2551
      }
    }
  
    cluster {
      seed-nodes = [
        "akka.tcp://ClusterSystem@127.0.0.1:2551",
        "akka.tcp://ClusterSystem@127.0.0.1:2552"]
  
      auto-down-unreachable-after = 10s
    }
    log-dead-letters = 0
    log-dead-letters-during-shutdown = off
  }
  
  PublishApp {
    akka {
      loglevel = "DEBUG"
      actor {
        provider = "akka.cluster.ClusterActorRefProvider"
      }
      remote {
        enabled-transports = ["akka.remote.netty.tcp"]
        netty.tcp {
          hostname = "127.0.0.1"
          port = 2552
        }
        log-sent-messages = on
        log-received-messages = on
      }
    }
  }
  </code></pre>
  
  <p>What I'm finding is that when I run the publisher's main, it will hang when attempting to publish to the "content" topic and the subscriber does not receive the message.</p>
  
  <p>The publisher's logs contain the following:</p>
  
  <blockquote>
    <p><code>[INFO] [12/09/2016 15:14:35.513] [ClusterSystem-akka.actor.default-dispatcher-18] [akka://ClusterSystem/system/distributedPubSubMediator] Message [java.lang.String] from Actor[akka://ClusterSystem/user/Publisher#-1478463431] to Actor[akka://ClusterSystem/system/distributedPubSubMediator#-1539813703] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.</code></p>
  </blockquote>
  
  <p>I have been poring over the docs, but it seems like the topic concept is mentioned as more of an afterthought. </p>
  
  <p>Why doesn't my subscriber receive this message?</p>