Skip to content

Commit

Permalink
Merge pull request akka#1993 from akka/wip-2922-event-bus-sample-patr…
Browse files Browse the repository at this point in the history
…iknw

!act,doc #2922 Doc event bus and fix Java API
  • Loading branch information
patriknw committed Feb 13, 2014
2 parents 12746fe + a247365 commit 947b49c
Show file tree
Hide file tree
Showing 12 changed files with 801 additions and 166 deletions.
24 changes: 17 additions & 7 deletions akka-actor-tests/src/test/scala/akka/event/EventBusSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,12 @@ class ActorEventBusSpec extends EventBusSpec("ActorEventBus") {
}

object ScanningEventBusSpec {
import akka.event.japi.ScanningEventBus

class MyScanningEventBus extends ScanningEventBus[Int, akka.japi.Procedure[Int], String] {
class MyScanningEventBus extends EventBus with ScanningClassification {
type Event = Int
type Subscriber = Procedure[Int]
type Classifier = String

protected def compareClassifiers(a: Classifier, b: Classifier): Int = a compareTo b
protected def compareSubscribers(a: Subscriber, b: Subscriber): Int = akka.util.Helpers.compareIdentityHash(a, b)

Expand All @@ -200,11 +203,17 @@ class ScanningEventBusSpec extends EventBusSpec("ScanningEventBus") {
}

object LookupEventBusSpec {
class MyLookupEventBus extends akka.event.japi.LookupEventBus[Int, akka.japi.Procedure[Int], String] {
protected def classify(event: Event): Classifier = event.toString
protected def compareSubscribers(a: Subscriber, b: Subscriber): Int = akka.util.Helpers.compareIdentityHash(a, b)
protected def mapSize = 32
protected def publish(event: Event, subscriber: Subscriber): Unit = subscriber(event)
class MyLookupEventBus extends EventBus with LookupClassification {
type Event = Int
type Subscriber = Procedure[Int]
type Classifier = String

override protected def classify(event: Int): String = event.toString
override protected def compareSubscribers(a: Procedure[Int], b: Procedure[Int]): Int =
akka.util.Helpers.compareIdentityHash(a, b)
override protected def mapSize = 32
override protected def publish(event: Int, subscriber: Procedure[Int]): Unit =
subscriber(event)
}
}

Expand All @@ -223,3 +232,4 @@ class LookupEventBusSpec extends EventBusSpec("LookupEventBus") {

def disposeSubscriber(system: ActorSystem, subscriber: BusType#Subscriber): Unit = ()
}

11 changes: 9 additions & 2 deletions akka-actor/src/main/scala/akka/event/EventBus.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ trait EventBus {
type Classifier
type Subscriber

//#event-bus-api
/**
* Attempts to register the subscriber to the specified Classifier
* @return true if successful and false if not (because it was already subscribed to that Classifier, or otherwise)
* @return true if successful and false if not (because it was already
* subscribed to that Classifier, or otherwise)
*/
def subscribe(subscriber: Subscriber, to: Classifier): Boolean

/**
* Attempts to deregister the subscriber from the specified Classifier
* @return true if successful and false if not (because it wasn't subscribed to that Classifier, or otherwise)
* @return true if successful and false if not (because it wasn't subscribed
* to that Classifier, or otherwise)
*/
def unsubscribe(subscriber: Subscriber, from: Classifier): Boolean

Expand All @@ -44,6 +47,7 @@ trait EventBus {
* Publishes the specified Event to this bus
*/
def publish(event: Event): Unit
//#event-bus-api
}

/**
Expand Down Expand Up @@ -118,6 +122,9 @@ trait LookupClassification { this: EventBus ⇒
*/
trait SubchannelClassification { this: EventBus

/**
* The logic to form sub-class hierarchy
*/
protected implicit def subclassification: Subclassification[Classifier]

// must be lazy to avoid initialization order problem with subclassification
Expand Down
195 changes: 180 additions & 15 deletions akka-actor/src/main/scala/akka/event/japi/EventBusJavaAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,89 @@
*/
package akka.event.japi

import akka.event._
import akka.util.Subclassification
import akka.actor.ActorRef

/**
* See documentation for [[akka.event.LookupClassification]]
* Java API: See documentation for [[akka.event.EventBus]]
* E is the Event type
* S is the Subscriber type
* C is the Classifier type
*/
abstract class LookupEventBus[E, S, C] extends EventBus with LookupClassification {
type Event = E
type Subscriber = S
type Classifier = C
trait EventBus[E, S, C] {

/**
* Attempts to register the subscriber to the specified Classifier
* @return true if successful and false if not (because it was already subscribed to that Classifier, or otherwise)
*/
def subscribe(subscriber: S, to: C): Boolean

/**
* Attempts to deregister the subscriber from the specified Classifier
* @return true if successful and false if not (because it wasn't subscribed to that Classifier, or otherwise)
*/
def unsubscribe(subscriber: S, from: C): Boolean

/**
* Attempts to deregister the subscriber from all Classifiers it may be subscribed to
*/
def unsubscribe(subscriber: S): Unit

/**
* Publishes the specified Event to this bus
*/
def publish(event: E): Unit
}

/**
* Java API: See documentation for [[akka.event.LookupClassification]]
* E is the Event type
* S is the Subscriber type
* C is the Classifier type
*/
abstract class LookupEventBus[E, S, C] extends EventBus[E, S, C] {
private val bus = new akka.event.EventBus with akka.event.LookupClassification {
type Event = E
type Subscriber = S
type Classifier = C

override protected def mapSize: Int = LookupEventBus.this.mapSize

override protected def compareSubscribers(a: S, b: S): Int =
LookupEventBus.this.compareSubscribers(a, b)

override protected def classify(event: E): C =
LookupEventBus.this.classify(event)

override protected def publish(event: E, subscriber: S): Unit =
LookupEventBus.this.publish(event, subscriber)
}

/**
* This is a size hint for the number of Classifiers you expect to have (use powers of 2)
*/
protected def mapSize(): Int

/**
* Provides a total ordering of Subscribers (think java.util.Comparator.compare)
*/
protected def compareSubscribers(a: S, b: S): Int

/**
* Returns the Classifier associated with the given Event
*/
protected def classify(event: E): C

/**
* Publishes the given Event to the given Subscriber
*/
protected def publish(event: E, subscriber: S): Unit

override def subscribe(subscriber: S, to: C): Boolean = bus.subscribe(subscriber, to)
override def unsubscribe(subscriber: S, from: C): Boolean = bus.unsubscribe(subscriber, from)
override def unsubscribe(subscriber: S): Unit = bus.unsubscribe(subscriber)
override def publish(event: E): Unit = bus.publish(event)

}

/**
Expand All @@ -23,10 +94,43 @@ abstract class LookupEventBus[E, S, C] extends EventBus with LookupClassificatio
* S is the Subscriber type
* C is the Classifier type
*/
abstract class SubchannelEventBus[E, S, C] extends EventBus with SubchannelClassification {
type Event = E
type Subscriber = S
type Classifier = C

abstract class SubchannelEventBus[E, S, C] extends EventBus[E, S, C] {
private val bus = new akka.event.EventBus with akka.event.SubchannelClassification {
type Event = E
type Subscriber = S
type Classifier = C

override protected def subclassification: Subclassification[Classifier] =
SubchannelEventBus.this.subclassification

override protected def classify(event: Event): Classifier =
SubchannelEventBus.this.classify(event)

override protected def publish(event: Event, subscriber: Subscriber): Unit =
SubchannelEventBus.this.publish(event, subscriber)
}

/**
* The logic to form sub-class hierarchy
*/
def subclassification: Subclassification[C]

/**
* Returns the Classifier associated with the given Event
*/
protected def classify(event: E): C

/**
* Publishes the given Event to the given Subscriber
*/
protected def publish(event: E, subscriber: S): Unit

override def subscribe(subscriber: S, to: C): Boolean = bus.subscribe(subscriber, to)
override def unsubscribe(subscriber: S, from: C): Boolean = bus.unsubscribe(subscriber, from)
override def unsubscribe(subscriber: S): Unit = bus.unsubscribe(subscriber)
override def publish(event: E): Unit = bus.publish(event)

}

/**
Expand All @@ -35,10 +139,49 @@ abstract class SubchannelEventBus[E, S, C] extends EventBus with SubchannelClass
* S is the Subscriber type
* C is the Classifier type
*/
abstract class ScanningEventBus[E, S, C] extends EventBus with ScanningClassification {
type Event = E
type Subscriber = S
type Classifier = C
abstract class ScanningEventBus[E, S, C] extends EventBus[E, S, C] {
private val bus = new akka.event.EventBus with akka.event.ScanningClassification {
type Event = E
type Subscriber = S
type Classifier = C

override protected def compareClassifiers(a: C, b: C): Int =
ScanningEventBus.this.compareClassifiers(a, b)

override protected def compareSubscribers(a: S, b: S): Int =
ScanningEventBus.this.compareSubscribers(a, b)

override protected def matches(classifier: C, event: E): Boolean =
ScanningEventBus.this.matches(classifier, event)

override protected def publish(event: E, subscriber: S): Unit =
ScanningEventBus.this.publish(event, subscriber)
}

/**
* Provides a total ordering of Classifiers (think java.util.Comparator.compare)
*/
protected def compareClassifiers(a: C, b: C): Int

/**
* Provides a total ordering of Subscribers (think java.util.Comparator.compare)
*/
protected def compareSubscribers(a: S, b: S): Int

/**
* Returns whether the specified Classifier matches the specified Event
*/
protected def matches(classifier: C, event: E): Boolean

/**
* Publishes the specified Event to the specified Subscriber
*/
protected def publish(event: E, subscriber: S): Unit

override def subscribe(subscriber: S, to: C): Boolean = bus.subscribe(subscriber, to)
override def unsubscribe(subscriber: S, from: C): Boolean = bus.unsubscribe(subscriber, from)
override def unsubscribe(subscriber: S): Unit = bus.unsubscribe(subscriber)
override def publish(event: E): Unit = bus.publish(event)
}

/**
Expand All @@ -47,6 +190,28 @@ abstract class ScanningEventBus[E, S, C] extends EventBus with ScanningClassific
* Means that ActorRefs "listen" to other ActorRefs
* E is the Event type
*/
abstract class ActorEventBus[E] extends akka.event.ActorEventBus with ActorClassification with ActorClassifier {
abstract class ActorEventBus[E] extends EventBus[E, ActorRef, ActorRef] {
private val bus = new akka.event.ActorEventBus with akka.event.ActorClassification with akka.event.ActorClassifier {
type Event = E

override protected def mapSize: Int = ActorEventBus.this.mapSize

override protected def classify(event: E): ActorRef =
ActorEventBus.this.classify(event)
}

/**
* This is a size hint for the number of Classifiers you expect to have (use powers of 2)
*/
protected def mapSize(): Int

/**
* Returns the Classifier associated with the given Event
*/
protected def classify(event: E): ActorRef

override def subscribe(subscriber: ActorRef, to: ActorRef): Boolean = bus.subscribe(subscriber, to)
override def unsubscribe(subscriber: ActorRef, from: ActorRef): Boolean = bus.unsubscribe(subscriber, from)
override def unsubscribe(subscriber: ActorRef): Unit = bus.unsubscribe(subscriber)
override def publish(event: E): Unit = bus.publish(event)
}
1 change: 0 additions & 1 deletion akka-docs/rst/additional/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ Additional Information
:maxdepth: 2

books
recipes
language-bindings
osgi
http
4 changes: 0 additions & 4 deletions akka-docs/rst/additional/recipes.rst

This file was deleted.

2 changes: 0 additions & 2 deletions akka-docs/rst/dev/developer-guidelines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ All code that is checked in **should** have tests. All testing is done with ``Sc
* Name tests as **Test.scala** if they do not depend on any external stuff. That keeps surefire happy.
* Name tests as **Spec.scala** if they have external dependencies.

There is a testing standard that should be followed: `Ticket001Spec <https://github.com/akka/akka/blob/master/akka-actor-tests/src/test/scala/akka/ticket/Ticket001Spec.scala>`_

Actor TestKit
^^^^^^^^^^^^^

Expand Down
Loading

0 comments on commit 947b49c

Please sign in to comment.