All Downloads are FREE. Search and download functionalities are using the official Maven repository.

astor_native0.4_2.12.0.3.0.source-code.Actors.scala Maven / Gradle / Ivy

The newest version!
package castor
import collection.mutable

abstract class BaseActor[T]()(implicit ac: Context) extends Actor[T]{
  private val queue = new mutable.Queue[(T, Context.Token)]()

  private var scheduled = false

  def send(t: T)
          (implicit fileName: sourcecode.FileName,
           line: sourcecode.Line): Unit = synchronized{
    val token = ac.reportSchedule(this, t, fileName, line)
    queue.enqueue((t, token))
    if (!scheduled){
      scheduled = true
      ac.execute(
        new Runnable{
          def run(): Unit = runWithItems()
        }
      )
    }
  }
  def sendAsync(f: scala.concurrent.Future[T])
               (implicit fileName: sourcecode.FileName,
                line: sourcecode.Line) = {
    f.onComplete{
      case scala.util.Success(v) => this.send(v)
      case scala.util.Failure(e) => ac.reportFailure(e)
    }
  }

  def runBatch0(msgs: Seq[(T, Context.Token)]): Unit
  private[this] def runWithItems(): Unit = {
    val msgs = synchronized(queue.dequeueAll(_ => true))

    runBatch0(msgs)

    synchronized{
      if (queue.nonEmpty) ac.execute(
        new Runnable{
          def run(): Unit = runWithItems()
        }
      )
      else{
        assert(scheduled)
        scheduled = false
      }
    }
  }
}

abstract class BatchActor[T]()(implicit ac: Context) extends BaseActor[T]{
  def runBatch(msgs: Seq[T]): Unit
  def runBatch0(msgs: Seq[(T, Context.Token)]): Unit = {
    try {
      msgs.foreach{case (m, token) => ac.reportRun(this, m, token)}
      runBatch(msgs.map(_._1))
    }
    catch{case e: Throwable => ac.reportFailure(e)}
    finally msgs.foreach{case (m, token) => ac.reportComplete(token)}

  }
}

abstract class SimpleActor[T]()(implicit ac: Context) extends BaseActor[T]{
  def run(msg: T): Unit
  override def runBatch0(msgs: Seq[(T, Context.Token)]): Unit = {
    for((msg, token) <- msgs) {
      try {
        ac.reportRun(this, msg, token)
        run(msg)
      }
      catch{case e: Throwable => ac.reportFailure(e)}
      finally ac.reportComplete(token)
    }
  }
}

abstract class StateMachineActor[T]()(implicit ac: Context) extends SimpleActor[T]() {
  class State(run0: T => State = null){
    def run = run0
  }
  protected[this] def initialState: State
  private[this] var state0: State = null
  protected[this] def state = {
    if (state0 == null) state0 = initialState
    state0
  }
  def run(msg: T): Unit = {
    state0 = state.run(msg)
  }
}

class ProxyActor[T, V](f: T => V, downstream: Actor[V])
                      (implicit ac: Context) extends SimpleActor[T]{
  def run(msg: T): Unit = downstream.send(f(msg))
}

class SplitActor[T](downstreams: Actor[T]*)
                   (implicit ac: Context) extends SimpleActor[T]{
  def run(msg: T): Unit = downstreams.foreach(_.send(msg))
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy