|
Akka/Scala example source code file (SystemMessage.scala)
The SystemMessage.scala Akka example source code/** * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com> */ package akka.dispatch.sysmsg import scala.annotation.tailrec import akka.actor.{ ActorInitializationException, InternalActorRef, ActorRef, PossiblyHarmful } /** * INTERNAL API * * Helper companion object for [[akka.dispatch.sysmsg.LatestFirstSystemMessageList]] and * [[akka.dispatch.sysmsg.EarliestFirstSystemMessageList]] */ private[akka] object SystemMessageList { final val LNil: LatestFirstSystemMessageList = new LatestFirstSystemMessageList(null) final val ENil: EarliestFirstSystemMessageList = new EarliestFirstSystemMessageList(null) @tailrec private[sysmsg] def sizeInner(head: SystemMessage, acc: Int): Int = if (head eq null) acc else sizeInner(head.next, acc + 1) @tailrec private[sysmsg] def reverseInner(head: SystemMessage, acc: SystemMessage): SystemMessage = { if (head eq null) acc else { val next = head.next head.next = acc reverseInner(next, head) } } } /** * * INTERNAL API * * Value class supporting list operations on system messages. The `next` field of [[SystemMessage]] * is hidden, and can only accessed through the value classes [[akka.dispatch.sysmsg.LatestFirstSystemMessageList]] and * [[akka.dispatch.sysmsg.EarliestFirstSystemMessageList]], abstracting over the fact that system messages are the * list nodes themselves. If used properly, this stays a compile time construct without any allocation overhead. * * This list is mutable. * * The type of the list also encodes that the messages contained are in reverse order, i.e. the head of the list is the * latest appended element. * */ private[akka] class LatestFirstSystemMessageList(val head: SystemMessage) extends AnyVal { import SystemMessageList._ /** * Indicates if the list is empty or not. This operation has constant cost. */ final def isEmpty: Boolean = head eq null /** * Indicates if the list has at least one element or not. This operation has constant cost. */ final def nonEmpty: Boolean = head ne null /** * Indicates if the list is empty or not. This operation has constant cost. */ final def size: Int = sizeInner(head, 0) /** * Gives back the list containing all the elements except the first. This operation has constant cost. * * *Warning:* as the underlying list nodes (the [[SystemMessage]] instances) are mutable, care * should be taken when passing the tail to other methods. [[akka.dispatch.sysmsg.SystemMessage#unlink]] should be * called on the head if one wants to detach the tail permanently. */ final def tail: LatestFirstSystemMessageList = new LatestFirstSystemMessageList(head.next) /** * Reverses the list. This operation mutates the underlying list. The cost of the call to reverse is linear in the * number of elements. * * The type of the returned list is of the opposite order: [[akka.dispatch.sysmsg.EarliestFirstSystemMessageList]] */ final def reverse: EarliestFirstSystemMessageList = new EarliestFirstSystemMessageList(reverseInner(head, null)) /** * Attaches a message to the current head of the list. This operation has constant cost. */ final def ::(msg: SystemMessage): LatestFirstSystemMessageList = { assert(msg ne null) msg.next = head new LatestFirstSystemMessageList(msg) } } /** * * INTERNAL API * * Value class supporting list operations on system messages. The `next` field of [[SystemMessage]] * is hidden, and can only accessed through the value classes [[akka.dispatch.sysmsg.LatestFirstSystemMessageList]] and * [[akka.dispatch.sysmsg.EarliestFirstSystemMessageList]], abstracting over the fact that system messages are the * list nodes themselves. If used properly, this stays a compile time construct without any allocation overhead. * * This list is mutable. * * This list type also encodes that the messages contained are in reverse order, i.e. the head of the list is the * latest appended element. * */ private[akka] class EarliestFirstSystemMessageList(val head: SystemMessage) extends AnyVal { import SystemMessageList._ /** * Indicates if the list is empty or not. This operation has constant cost. */ final def isEmpty: Boolean = head eq null /** * Indicates if the list has at least one element or not. This operation has constant cost. */ final def nonEmpty: Boolean = head ne null /** * Indicates if the list is empty or not. This operation has constant cost. */ final def size: Int = sizeInner(head, 0) /** * Gives back the list containing all the elements except the first. This operation has constant cost. * * *Warning:* as the underlying list nodes (the [[SystemMessage]] instances) are mutable, care * should be taken when passing the tail to other methods. [[akka.dispatch.sysmsg.SystemMessage#unlink]] should be * called on the head if one wants to detach the tail permanently. */ final def tail: EarliestFirstSystemMessageList = new EarliestFirstSystemMessageList(head.next) /** * Reverses the list. This operation mutates the underlying list. The cost of the call to reverse is linear in the * number of elements. * * The type of the returned list is of the opposite order: [[akka.dispatch.sysmsg.LatestFirstSystemMessageList]] */ final def reverse: LatestFirstSystemMessageList = new LatestFirstSystemMessageList(reverseInner(head, null)) /** * Attaches a message to the current head of the list. This operation has constant cost. */ final def ::(msg: SystemMessage): EarliestFirstSystemMessageList = { assert(msg ne null) msg.next = head new EarliestFirstSystemMessageList(msg) } /** * Prepends a list in a reversed order to the head of this list. The prepended list will be reversed during the process. * * Example: (3, 4, 5) reversePrepend (2, 1, 0) == (0, 1, 2, 3, 4, 5) * * The cost of this operation is linear in the size of the list that is to be prepended. */ final def reverse_:::(other: LatestFirstSystemMessageList): EarliestFirstSystemMessageList = { var remaining = other var result = this while (remaining.nonEmpty) { val msg = remaining.head remaining = remaining.tail result ::= msg } result } } /** * System messages are handled specially: they form their own queue within * each actor’s mailbox. This queue is encoded in the messages themselves to * avoid extra allocations and overhead. The next pointer is a normal var, and * it does not need to be volatile because in the enqueuing method its update * is immediately succeeded by a volatile write and all reads happen after the * volatile read in the dequeuing thread. Afterwards, the obtained list of * system messages is handled in a single thread only and not ever passed around, * hence no further synchronization is needed. * * INTERNAL API * * ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS ⬅⬅⬅ */ private[akka] sealed trait SystemMessage extends PossiblyHarmful with Serializable { // Next fields are only modifiable via the SystemMessageList value class @transient private[sysmsg] var next: SystemMessage = _ def unlink(): Unit = next = null def unlinked: Boolean = next eq null } /** * INTERNAL API */ private[akka] trait StashWhenWaitingForChildren /** * INTERNAL API */ private[akka] trait StashWhenFailed /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Create(failure: Option[ActorInitializationException]) extends SystemMessage // sent to self from Dispatcher.register /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Recreate(cause: Throwable) extends SystemMessage with StashWhenWaitingForChildren // sent to self from ActorCell.restart /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Suspend() extends SystemMessage with StashWhenWaitingForChildren // sent to self from ActorCell.suspend /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Resume(causedByFailure: Throwable) extends SystemMessage with StashWhenWaitingForChildren // sent to self from ActorCell.resume /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Terminate() extends SystemMessage // sent to self from ActorCell.stop /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Supervise(child: ActorRef, async: Boolean) extends SystemMessage // sent to supervisor ActorRef from ActorCell.start /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] case class Watch(watchee: InternalActorRef, watcher: InternalActorRef) extends SystemMessage // sent to establish a DeathWatch /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Unwatch(watchee: ActorRef, watcher: ActorRef) extends SystemMessage // sent to tear down a DeathWatch /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] case object NoMessage extends SystemMessage // switched into the mailbox to signal termination /** * INTERNAL API */ @SerialVersionUID(1L) private[akka] final case class Failed(child: ActorRef, cause: Throwable, uid: Int) extends SystemMessage with StashWhenFailed with StashWhenWaitingForChildren @SerialVersionUID(1L) private[akka] final case class DeathWatchNotification( actor: ActorRef, existenceConfirmed: Boolean, addressTerminated: Boolean) extends SystemMessage Other Akka source code examplesHere is a short list of links related to this Akka SystemMessage.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.