cc.otavia.core.interceptor

Members list

Type members

Classlikes

abstract class InterceptorActor[M <: Call] extends StateActor[M]

Base class for interceptor actors that wrap a target Address and forward messages through a chain.

Base class for interceptor actors that wrap a target Address and forward messages through a chain.

Interceptors are normal actors that use the standard Stack coroutine pattern (override resumeAsk / resumeNotice with state matching). The forwardAsk helper encapsulates the common pattern of forwarding to the next address and suspending until the reply arrives.

Concept mapping (for understanding, not API):

// Industry concept        -> Otavia equivalent
// chain.proceed()         -> forwardAsk(stack)
// preHandle return false  -> stack.return(rejectReply) without calling forwardAsk
// postHandle              -> match FutureState with ForwardStateId, process reply, then stack.return
// onion model             -> Stack StartState -> suspend -> FutureState naturally implements this

Example - logging interceptor:

class LoggingInterceptor(val next: Address[HttpRequest]) extends InterceptorActor[HttpRequest] {
  override protected def resumeAsk(stack: AskStack[HttpRequest & Ask[? <: Reply]]): StackYield = {
    stack.state match {
      case _: StartState =>
        stack.attach(System.nanoTime())
        forwardAsk(stack)
      case state: FutureState[_] if state.id == ForwardStateId =>
        val elapsed = (System.nanoTime() - stack.attach[Long]) / 1_000_000
        logger.info(s"${stack.ask.method} ${stack.ask.path} -> ${elapsed}ms")
        stack.`return`(state.future.getNow.asInstanceOf)
    }
  }
}

Type parameters

M

the message type this interceptor handles, must match the target actor's type

Attributes

Supertypes
class StateActor[M]
trait Actor[M]
class Object
trait Matchable
class Any