1
\$\begingroup\$

I have a trait that is to be mixed-in with existing types of Actor classes in Akka and offer a certain functionality.

To offer better maintenance, I am using the stackable trait pattern. The integration with different kinds of actor(say PersistentActor or PersistentFSM) happens at a Impl level. Now all these Impl trait have a base impl trait. This base trait in turn, depends on some fields which are defined in a Logic trait:

trait QueryViewLogic {

def viewId: String

def queryId: String

  ...

}

//This needs to be mixed in to create and enable the pipelines to be assembled.
trait QueryViewLogicImpl extends Snapshotter
with ActorLogging with QueryViewLogic with ReadJournalQuerySupport {

def bookKeeping(): Unit = {...}

def performSnapshot: Receive = {...}
...

}

The actual implementation for say a persistentActor will be defined as below:

//The view Persistent-Actors can mix this trait in to specify the building blocks of QueryView.
abstract class QueryViewBase[D](implicit val snapshotData: ClassTag[D])
extends PersistentActor with QueryViewLogic {

type SnapshotData = D

def persistenceId: String = viewId

def receiveRecover: Receive = Map.empty

def receiveCommand: Receive = receiveReads orElse receiveJournalEvents

def receiveJournalEvents: Receive

def receiveReads: Receive
}

and then:

//The view Persistent-Actors extending QueryViewBase need to mix this in to get the QueryView machinery working.
trait QueryViewImpl extends PersistentActor with QueryViewLogicImpl {

override def receiveRecover: Receive = receiveQueryViewSnapshot

abstract override def receiveCommand: Receive = {
  performSnapshot orElse
    (queryViewCommandPipeline andThen (super.receiveCommand orElse unhandledCommand))
    }

}

So the client, would mix in the Logic trait to provide the fields of interest, and then the impl class mixes in the class providing the information above and mixes in the trait that actually puts together the pipelines introduced above according to the stackable trait pattern. see an example here.

  • Firstly, I would like to have feedback on the names of the four traits mentioned above.

  • secondly, taking the demo as an example, the point of having an AccountView and a separate AccountViewImpl was to separate the functionality of responding to events and that of the mechanism for fetching the events, for better maintenance, so that the users of this functionality, only concerns themselves with the former. Is this benefit shadowed by the added complexity in the code?

  • I'd be interested in suggestions for better names for the client users of these traits, namely AccountView and AccountViewImpl.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.