Сочинение актеров - PullRequest
8 голосов
/ 09 марта 2010

Я реализовал черту Listenable / Listener, которую можно добавить в Actors. Мне интересно, возможно ли присоединить этот стиль черты к актеру без явного вызова метода listenerHandler ?

Также я ожидал найти эту функцию в библиотеке Akka. Я что-то упустил или есть какая-то причина, по которой Акка не включит это?

trait Listenable { this: Actor =>
    private var listeners: List[Actor] = Nil

    protected def listenerHandler: PartialFunction[Any, Unit] = {
        case AddListener(who) => listeners = who :: listeners
    }

    protected def notifyListeners(event: Any) = {
        listeners.foreach(_.send(event))
    }
}

class SomeActor extends Actor with Listenable
{
    def receive = listenerHandler orElse {
        case Start => notifyListeners(Started())
        case Stop => notifyListeners(Stopped())
    }
}

Ответы [ 5 ]

5 голосов
/ 09 марта 2010

Почему бы не расширить Actor напрямую или, если вы хотите, чтобы неакторы также были прослушиваемыми, создать ListenableActor, который расширяет Actor с Listenable?

Затем вы переопределите receive в Actor, как вы делали выше (за исключением того, что вы также хотите вызвать super.receive, не так ли? ).

2 голосов
/ 22 июля 2010

Почему я не видел этот вопрос раньше, ну, лучше поздно, чем никогда:

http://doc.akka.io/docs/akka/snapshot/scala/routing.html

2 голосов
/ 10 марта 2010

Я предлагаю вам расширить Actor и использовать abstract override.

0 голосов
/ 05 сентября 2011

В Akka есть встроенная поддержка для этого: https://github.com/jboner/akka/blob/release-1.2/akka-actor/src/main/scala/akka/routing/Listeners.scala

0 голосов
/ 13 марта 2010

Вот решение (модифицированная версия примера из Beginning Scala):

import se.scalablesolutions.akka.actor.Actor

case class AddListener(who: Actor)
case class RemoveListener(who: Actor)

class ListenableActor extends Actor {
    private var listeners: List[Actor] = Nil

    def receive = {
        case AddListener(who) => listeners ::= who
        case RemoveListener(who) => listeners.filter(_ ne who)
    }

    protected def notifyListeners(event: Any) = {
        listeners.foreach(_.send(event))
    }
}

class ImplementingActor extends ListenableActor {
    override def receive = {
        super.receive orElse {
            case Message(content) => println(content)
        }
    }
}
...