Skip to content

Instantly share code, notes, and snippets.

@abdheshkumar
Last active April 26, 2017 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abdheshkumar/ea550ac6f1aa1eeee32f2bf8997db1c4 to your computer and use it in GitHub Desktop.
Save abdheshkumar/ea550ac6f1aa1eeee32f2bf8997db1c4 to your computer and use it in GitHub Desktop.
import freestyle._
import freestyle.implicits._
import freestyle.implicits.interpretAp
import cats.implicits._
case class ValidationResult(isValid:Boolean, events:List[Event])
trait Command
case class UnknownCommand(cmd:Any) extends Command
sealed trait Event {val name:String}
@free trait LoggerOp[A[_]] {
def debug(msg: String, o: List[Event]): FreeS[A, Unit]
def info(msg: String, o: List[Event]): FreeS[A, Unit]
def warn(msg: String, o: List[Event]): FreeS[A, Unit]
def error(msg: String, o: List[Event]): FreeS[A, Unit]
}
@free trait ActorOp[A[_]] {
def send(a: Any, to: ActorRef): FreeS[A, Unit]
def sendToActorSelection(a: Any, context: ActorContext, path: String): FreeS[A, Unit]
def tellFrom(a: Any, to: ActorRef, from: ActorRef): FreeS[A, Unit]
def timeOut(context: ActorContext, time: Int): FreeS[A, Unit]
def transitionState(context: ActorContext, state: () => Receive): FreeS[A, Unit]
def stopActor(context: ActorContext, victim: ActorRef): FreeS[A, Unit]
def createActor(props: Props, name: String, context: ActorContext): FreeS[A, ActorRef]
}
@module trait FinalApp[F[_]] {
val loggerOp: LoggerOp[F]
val actorOp: ActorOp[F]
}
type OutputState[T] = State[T, ?]
implicit val StatelessLoggerInterpreter = new LoggerOp.Handler[Id] {
def debug(msg: String, o: List[Event]): Id[Unit] = println(s"[Debug] : ${msg}")
def info(msg: String, o: List[Event]): Id[Unit] = println(s"[Info] : ${msg}")
def warn(msg: String, o: List[Event]): Id[Unit] = println(s"[Warn] : ${msg}")
def error(msg: String, o: List[Event]): Id[Unit] = println(s"[Error] : ${msg}")
}
implicit val StatelessActorOpsInterpreter = new ActorOp.Handler[Id] {
def send(a: Any, to: ActorRef): Id[Unit] = to ! a
def sendToActorSelection(a: Any, context: ActorContext, path: String): Id[Unit] = context.actorSelection(path) ! a
def tellFrom(a: Any, to: ActorRef, from: ActorRef): Id[Unit] = to tell(a, from)
def timeOut(context: ActorContext, time: Int): Id[Unit] = {
if (time == 0) {
context.setReceiveTimeout(Duration.Undefined)
}
else {
context.setReceiveTimeout(time seconds)
}
}
def transitionState(context: ActorContext, state: () => Receive): Id[Unit] = context.become(state())
def stopActor(context: ActorContext, victim: ActorRef): Id[Unit] = context.stop(victim)
def createActor(props: Props, name: String, context: ActorContext): Id[Unit] = context.actorOf(props, name)
}
final def handleCommand[T[?], A <: ActorMessage](message: A,
validate: (Command) => ValidationResult,
success: (A, ActorContext) => FreeS[T, List[Event]],
failure: (A, ActorContext) => FreeS[T, List[Event]],
logger: (String, List[Event]) => FreeS[T, List[Event]],
timeOut: => FreeS[T, List[Event]]
)(implicit context: ActorContext, interpreter: FunctionK[T, cats.Id]): List[Event] = {
(message.command match {
case x: UnknownCommand => logger(s"Stateless -- Unknown Message ${x}", Nil).exec[Id](interpreter)
case x: ReceiveTimeout => timeOut.exec[Id](interpreter) //timeOut.foldMap[Id](interpreter)
case x: Command =>
val validationResult = validate(x)
validationResult.events ++
(if (validationResult.isValid) {
success(message, context).exec[Id](interpreter)
} else {
failure(message, context).exec[Id](interpreter)
}
)
case x => logger(s"Stateless -- Unknown Message ${x}", Nil).exec[Id](interpreter)
}).filter(event => persistenceFilter(event, persistenceLevel))
}
object Implicits {
//I want to combine interpreters
implicit val loggerAndActorInterpreter: FinalApp.Op ~> Id = StatelessLoggerInterpreter or StatelessActorOpsInterpreter
}
I want to call handleCommand function:
handleCommand[FinalApp.Op,ActionMessage](message,
validate,
successWhenSleeping,
failure,
logger,
setTimeOutAndMoveOn(TimedOut,node,action,context))(Implicits.loggerAndActorInterpreter)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment