2017-01-03 2 views
1

Я пытаюсь заблокировать возможность наличия участников в системе, которые имеют одно и то же имя (они находятся на разных путях, так что InvalidActorNameException не будет выброшено)AKKA- как заблокировать создание актера, если его имя не является uniqe в кластере

application.conf:

someactor { 
    akka.remote.netty.tcp.port = 6405 
    akka.cluster.auto-down-unreachable-after = 20s 
    akka.cluster.seed-nodes = ["akka.tcp://[email protected]:2552"] 
    akka.actor.provider = "akka.cluster.ClusterActorRefProvider" 
} 

Главная:

object SomeActor extends App { 
    val system = ActorSystem("mySys", ConfigFactory.load("application").getConfig("someactor")) 
    val t = system.actorOf(Props(classOf[SomeActor]), "someActor") 
} 

Актер:

class SomeActor extends Actor { 
    val cluster = Cluster(SomeActor.system) 
    override def receive = { 
     case x=> println(x) 
    } 
} 

Если вы запускаете приложение один раз с портом 6405 и один раз с портом 6406, то приложение будет работать, но я хочу, чтобы он заметил, что система уже содержит актера с именем «someActor» и блокирует этот вызов.

Я не против добавления имени в качестве роли или другой конфигурации, если он сможет блокировать это, но я не могу иметь состояние, подобное карте, содержащей уже существующие имена (или актора, содержащего карта с передачей сообщений) или иметь длительную операцию, например actorSelection (и в любом случае они не будут безопасными, если из нескольких мест параллельно вызывается actorOf).

+2

Звучит как подход, склонный к условиям гонки. Что делать, если оба игрока создаются в один и тот же момент времени на разных узлах? Итак, возможно, объясните, чего вы хотите добиться в первую очередь? (Вы после чего-то вроде ClusterSingleton? ClusterSingleton содержит аналогичную проверку, где одиночки должны жить на самом старом узле, который, как известно, согласовывается всеми узлами в кластере.) – jrudolph

+1

Я думаю, что вы действительно ищете кластерное окошко и/или кластеров. – Ryan

+0

Исправить меня, если я ошибаюсь, но не кластер singleton блокирует создание актеров по типу?если это не сработает для меня, потому что я хочу создать много актеров класса 'SomeActor', я просто не хочу иметь этих актеров с тем же именем (это имя - уникальный идентификатор, который у меня есть в моей программе для каждого рабочего актер, поэтому я не могу дублировать) –

ответ

0

Мне удалось сделать это с помощью Cluster Aware Router группы типов (каждый актер будет работать на удаленном узле). Роль узла - это имя «someActor», я инициализирую актера на удаленном узле с тем же именем «someActor» (так что я узнаю, что путь к этому актору), и router totalInstances config равен 1 (так что только один узел будет частью маршрутизатора)

маршрутизатор INIT:

context.actorOf(
     ClusterRouterGroup(RoundRobinGroup(Nil), ClusterRouterGroupSettings(
      totalInstances = 1, routeesPaths = List("/user/someActor"), 
      allowLocalRoutees = false, useRole = Some("someActor"))).props() 

удаленный актер:

object RemoteActor extends App{ 
    val system = ActorSystem("mySys",ConfigFactory.load("remoteActorConfig")) 
    system.actorOf(Props[RemoteActor], "someActor") 

} 

class RemoteActor extends Actor with ActorLogging{ 
    override def receive: Receive = { 
    case x => 
     log.info(s"got: $x}") 
    } 
} 

и remoteActorConfig:

akka{ 
    remote.netty.tcp.port = 0 
    cluster.auto-down-unreachable-after = 20s 
    cluster.seed-nodes = ["akka.tcp://[email protected]:2552"] 
    cluster.roles.1 = "someActor" 
    actor.provider = "akka.cluster.ClusterActorRefProvider" 
} 

Теперь, если я запустил дважды RemoteActor, запустите приложение, которое инициализирует маршрутизатор и отправляет широковещательное сообщение только на маршрутизатор, и только один актер RemoterActor получит его (и всегда тот же).

0

Если вам действительно нужны 100% -ные неперекрывающиеся UUIDs, почему бы вам просто не создать единую службу для назначения UUID и получить свой UUID до создания актера?

Вы также можете использовать SHA-хэш на имени хоста, имени порта и имени актера и увеличивающемся номере работника на актера.

Вы также можете настроить кластер-маршрутизатор для рабочих, и akka сделает все это для вас, и вам нужно будет отправить только один ActorRef для доступа к рабочему пулу.

+0

Идентификатор uniqe уже существует в системе, поэтому я не могу создать свой собственный –

Смежные вопросы