Saving the planet and shufflin'

This commit is contained in:
Viktor Klang 2012-05-18 13:37:26 +02:00
parent 72f12c89cd
commit 5eba9fceef
10 changed files with 177 additions and 148 deletions

View file

@ -19,7 +19,7 @@ object EventStreamSpec {
loglevel = INFO
event-handlers = ["akka.event.EventStreamSpec$MyLog", "%s"]
}
""".format(Logging.StandardOutLoggerName))
""".format(Logging.StandardOutLogger.getClass.getName))
val configUnhandled = ConfigFactory.parseString("""
akka {

View file

@ -93,11 +93,17 @@ import akka.japi.{ Creator }
abstract class UntypedActor extends Actor {
/**
* To be implemented by concrete UntypedActor. Defines the message handler.
* To be implemented by concrete UntypedActor, this defines the behavior of the
* UntypedActor.
*/
@throws(classOf[Exception])
def onReceive(message: Any): Unit
/**
* Returns this UntypedActor's UntypedActorContext
* The UntypedActorContext is not thread safe so do not expose it outside of the
* UntypedActor.
*/
def getContext(): UntypedActorContext = context.asInstanceOf[UntypedActorContext]
/**
@ -150,9 +156,7 @@ abstract class UntypedActor extends Actor {
*/
override def postRestart(reason: Throwable): Unit = super.postRestart(reason)
final protected def receive = {
case msg onReceive(msg)
}
final protected def receive = { case msg onReceive(msg) }
}
/**

View file

@ -97,6 +97,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
}
}
//INTERNAL API
private def config(id: String): Config = {
import scala.collection.JavaConverters._
def simpleName = id.substring(id.lastIndexOf('.') + 1)
@ -106,6 +107,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
.withFallback(defaultDispatcherConfig)
}
//INTERNAL API
private def idConfig(id: String): Config = {
import scala.collection.JavaConverters._
ConfigFactory.parseMap(Map("id" -> id).asJava)
@ -123,9 +125,7 @@ class Dispatchers(val settings: ActorSystem.Settings, val prerequisites: Dispatc
*
* INTERNAL USE ONLY
*/
private[akka] def from(cfg: Config): MessageDispatcher = {
configuratorFrom(cfg).dispatcher()
}
private[akka] def from(cfg: Config): MessageDispatcher = configuratorFrom(cfg).dispatcher()
/**
* Creates a MessageDispatcherConfigurator from a Config.

View file

@ -16,7 +16,10 @@ import akka.actor.ActorSystem
class MessageQueueAppendFailedException(message: String, cause: Throwable = null) extends AkkaException(message, cause)
object Mailbox {
/**
* INTERNAL API
*/
private[akka] object Mailbox {
type Status = Int
@ -40,6 +43,7 @@ object Mailbox {
* Mailbox and InternalMailbox is separated in two classes because ActorCell is needed for implementation,
* but can't be exposed to user defined mailbox subclasses.
*
* INTERNAL API
*/
private[akka] abstract class Mailbox(val actor: ActorCell, val messageQueue: MessageQueue)
extends SystemMessageQueue with Runnable {
@ -244,6 +248,10 @@ private[akka] abstract class Mailbox(val actor: ActorCell, val messageQueue: Mes
}
}
/**
* A MessageQueue is the user-message "lane" of an Akka Mailbox.
* It needs to atleast support N producers and 1 consumer thread-safely.
*/
trait MessageQueue {
/**
* Try to enqueue the message to this queue, or throw an exception.
@ -325,6 +333,9 @@ private[akka] trait DefaultSystemMessageQueue { self: Mailbox ⇒
def hasSystemMessages: Boolean = systemQueueGet ne null
}
/**
* A QueueBasedMessageQueue is a MessageQueue backed by a java.util.Queue
*/
trait QueueBasedMessageQueue extends MessageQueue {
def queue: Queue[Envelope]
def numberOfMessages = queue.size
@ -340,11 +351,19 @@ trait QueueBasedMessageQueue extends MessageQueue {
}
}
/**
* UnboundedMessageQueueSemantics adds unbounded semantics to a QueueBasedMessageQueue,
* i.e. a non-blocking enqueue and dequeue.
*/
trait UnboundedMessageQueueSemantics extends QueueBasedMessageQueue {
def enqueue(receiver: ActorRef, handle: Envelope): Unit = queue add handle
def dequeue(): Envelope = queue.poll()
}
/**
* BoundedMessageQueueSemantics adds bounded semantics to a QueueBasedMessageQueue,
* i.e. blocking enqueue with timeout
*/
trait BoundedMessageQueueSemantics extends QueueBasedMessageQueue {
def pushTimeOut: Duration
override def queue: BlockingQueue[Envelope]
@ -360,17 +379,28 @@ trait BoundedMessageQueueSemantics extends QueueBasedMessageQueue {
def dequeue(): Envelope = queue.poll()
}
/**
* DequeBasedMessageQueue refines QueueBasedMessageQueue to be backed by a java.util.Deque
*/
trait DequeBasedMessageQueue extends QueueBasedMessageQueue {
def queue: Deque[Envelope]
def enqueueFirst(receiver: ActorRef, handle: Envelope): Unit
}
/**
* UnboundedDequeBasedMessageQueueSemantics adds unbounded semantics to a DequeBasedMessageQueue,
* i.e. a non-blocking enqueue and dequeue.
*/
trait UnboundedDequeBasedMessageQueueSemantics extends DequeBasedMessageQueue {
def enqueue(receiver: ActorRef, handle: Envelope): Unit = queue add handle
def enqueueFirst(receiver: ActorRef, handle: Envelope): Unit = queue addFirst handle
def dequeue(): Envelope = queue.poll()
}
/**
* BoundedMessageQueueSemantics adds bounded semantics to a DequeBasedMessageQueue,
* i.e. blocking enqueue with timeout
*/
trait BoundedDequeBasedMessageQueueSemantics extends DequeBasedMessageQueue {
def pushTimeOut: Duration
override def queue: BlockingDeque[Envelope]
@ -393,14 +423,14 @@ trait BoundedDequeBasedMessageQueueSemantics extends DequeBasedMessageQueue {
}
/**
* Mailbox configuration.
* MailboxType is a factory to create MessageQueues for an optionally provided ActorContext
*/
trait MailboxType {
def create(owner: Option[ActorContext]): MessageQueue
}
/**
* It's a case class for Java (new UnboundedMailbox)
* UnboundedMailbox is the default unbounded MailboxType used by Akka Actors.
*/
case class UnboundedMailbox() extends MailboxType {
@ -412,6 +442,9 @@ case class UnboundedMailbox() extends MailboxType {
}
}
/**
* BoundedMailbox is the default bounded MailboxType used by Akka Actors.
*/
case class BoundedMailbox( final val capacity: Int, final val pushTimeOut: Duration) extends MailboxType {
def this(settings: ActorSystem.Settings, config: Config) = this(config.getInt("mailbox-capacity"),
@ -428,17 +461,20 @@ case class BoundedMailbox( final val capacity: Int, final val pushTimeOut: Durat
}
/**
* Extend me to provide the comparator
* UnboundedPriorityMailbox is an unbounded mailbox that allows for priorization of its contents.
* Extend this class and provide the Comparator in the constructor.
*/
class UnboundedPriorityMailbox( final val cmp: Comparator[Envelope]) extends MailboxType {
class UnboundedPriorityMailbox( final val cmp: Comparator[Envelope], final val initialCapacity: Int) extends MailboxType {
def this(cmp: Comparator[Envelope]) = this(cmp, 11)
final override def create(owner: Option[ActorContext]): MessageQueue =
new PriorityBlockingQueue[Envelope](11, cmp) with QueueBasedMessageQueue with UnboundedMessageQueueSemantics {
new PriorityBlockingQueue[Envelope](initialCapacity, cmp) with QueueBasedMessageQueue with UnboundedMessageQueueSemantics {
final def queue: Queue[Envelope] = this
}
}
/**
* Extend me to provide the comparator
* BoundedPriorityMailbox is a bounded mailbox that allows for priorization of its contents.
* Extend this class and provide the Comparator in the constructor.
*/
class BoundedPriorityMailbox( final val cmp: Comparator[Envelope], final val capacity: Int, final val pushTimeOut: Duration) extends MailboxType {
@ -452,6 +488,9 @@ class BoundedPriorityMailbox( final val cmp: Comparator[Envelope], final val cap
}
}
/**
* UnboundedDequeBasedMailbox is an unbounded MailboxType, backed by a Deque.
*/
case class UnboundedDequeBasedMailbox() extends MailboxType {
def this(settings: ActorSystem.Settings, config: Config) = this()
@ -462,6 +501,9 @@ case class UnboundedDequeBasedMailbox() extends MailboxType {
}
}
/**
* BoundedDequeBasedMailbox is an bounded MailboxType, backed by a Deque.
*/
case class BoundedDequeBasedMailbox( final val capacity: Int, final val pushTimeOut: Duration) extends MailboxType {
def this(settings: ActorSystem.Settings, config: Config) = this(config.getInt("mailbox-capacity"),

View file

@ -12,7 +12,7 @@ import akka.actor._
* A failed subscribe should also only mean that the Classifier (ActorRef) that is listened to is already shut down
* See LocalDeathWatch for semantics
*/
trait DeathWatch extends ActorEventBus with ActorClassifier {
abstract class DeathWatch extends ActorEventBus with ActorClassifier {
type Event = Terminated
protected final def classify(event: Event): Classifier = event.actor

View file

@ -182,10 +182,9 @@ trait SubchannelClassification { this: EventBus ⇒
*/
trait ScanningClassification { self: EventBus
protected final val subscribers = new ConcurrentSkipListSet[(Classifier, Subscriber)](new Comparator[(Classifier, Subscriber)] {
def compare(a: (Classifier, Subscriber), b: (Classifier, Subscriber)): Int = {
val cM = compareClassifiers(a._1, b._1)
if (cM != 0) cM
else compareSubscribers(a._2, b._2)
def compare(a: (Classifier, Subscriber), b: (Classifier, Subscriber)): Int = compareClassifiers(a._1, b._1) match {
case 0 compareSubscribers(a._2, b._2)
case other other
}
})
@ -238,7 +237,7 @@ trait ActorClassification { this: ActorEventBus with ActorClassifier ⇒
import java.util.concurrent.ConcurrentHashMap
import scala.annotation.tailrec
private val empty = TreeSet.empty[ActorRef]
protected val mappings = new ConcurrentHashMap[ActorRef, TreeSet[ActorRef]](mapSize)
private val mappings = new ConcurrentHashMap[ActorRef, TreeSet[ActorRef]](mapSize)
@tailrec
protected final def associate(monitored: ActorRef, monitor: ActorRef): Boolean = {
@ -320,9 +319,9 @@ trait ActorClassification { this: ActorEventBus with ActorClassifier ⇒
*/
protected def mapSize: Int
def publish(event: Event): Unit = {
val receivers = mappings.get(classify(event))
if (receivers ne null) receivers foreach { _ ! event }
def publish(event: Event): Unit = mappings.get(classify(event)) match {
case null ()
case some some foreach { _ ! event }
}
def subscribe(subscriber: Subscriber, to: Classifier): Boolean = associate(to, subscriber)

View file

@ -29,7 +29,7 @@ trait LoggingBus extends ActorEventBus {
import Logging._
private val guard = new ReentrantGuard
private val guard = new ReentrantGuard //Switch to ReentrantReadWrite
private var loggers = Seq.empty[ActorRef]
private var _logLevel: LogLevel = _
@ -97,7 +97,7 @@ trait LoggingBus extends ActorEventBus {
val myloggers =
for {
loggerName defaultLoggers
if loggerName != StandardOutLoggerName
if loggerName != StandardOutLogger.getClass.getName
} yield {
try {
system.dynamicAccess.getClassFor[Actor](loggerName) match {
@ -129,7 +129,7 @@ trait LoggingBus extends ActorEventBus {
case _: InvalidActorNameException // ignore if it is already running
}
publish(Debug(logName, this.getClass, "Default Loggers started"))
if (!(defaultLoggers contains StandardOutLoggerName)) {
if (!(defaultLoggers contains StandardOutLogger.getClass.getName)) {
unsubscribe(StandardOutLogger)
}
} catch {
@ -163,6 +163,9 @@ trait LoggingBus extends ActorEventBus {
publish(Debug(simpleName(this), this.getClass, "all default loggers stopped"))
}
/**
* INTERNAL API
*/
private def addLogger(system: ActorSystemImpl, clazz: Class[_ <: Actor], level: LogLevel, logName: String): ActorRef = {
val name = "log" + Extension(system).id() + "-" + simpleName(clazz)
val actor = system.systemActorOf(Props(clazz), name)
@ -361,17 +364,33 @@ object LogSource {
*/
object Logging {
/**
* Returns a 'safe' getSimpleName for the provided object's Class
* @param obj
* @return the simple name of the given object's Class
*/
def simpleName(obj: AnyRef): String = simpleName(obj.getClass)
/**
* Returns a 'safe' getSimpleName for the provided Class
* @param obj
* @return the simple name of the given Class
*/
def simpleName(clazz: Class[_]): String = {
val n = clazz.getName
val i = n.lastIndexOf('.')
n.substring(i + 1)
}
object Extension extends ExtensionKey[LogExt]
/**
* INTERNAL API
*/
private[akka] object Extension extends ExtensionKey[LogExt]
class LogExt(system: ExtendedActorSystem) extends Extension {
/**
* INTERNAL API
*/
private[akka] class LogExt(system: ExtendedActorSystem) extends Extension {
private val loggerId = new AtomicInteger
def id() = loggerId.incrementAndGet()
}
@ -431,12 +450,6 @@ object Logging {
// these type ascriptions/casts are necessary to avoid CCEs during construction while retaining correct type
val AllLogLevels = Seq(ErrorLevel: AnyRef, WarningLevel, InfoLevel, DebugLevel).asInstanceOf[Seq[LogLevel]]
val errorFormat = "[ERROR] [%s] [%s] [%s] %s\n%s".intern
val errorFormatWithoutCause = "[ERROR] [%s] [%s] [%s] %s".intern
val warningFormat = "[WARN] [%s] [%s] [%s] %s".intern
val infoFormat = "[INFO] [%s] [%s] [%s] %s".intern
val debugFormat = "[DEBUG] [%s] [%s] [%s] %s".intern
/**
* Obtain LoggingAdapter for the given actor system and source object. This
* will use the systems event stream and include the systems address in the
@ -624,27 +637,34 @@ object Logging {
// weird return type due to binary compatibility
def loggerInitialized(): LoggerInitialized.type = LoggerInitialized
/**
* LoggerInitializationException is thrown to indicate that there was a problem initializing a logger
* @param msg
*/
class LoggerInitializationException(msg: String) extends AkkaException(msg)
trait StdOutLogger {
import java.text.SimpleDateFormat
import java.util.Date
val dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.S")
private val dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.S")
private val errorFormat = "[ERROR] [%s] [%s] [%s] %s\n%s".intern
private val errorFormatWithoutCause = "[ERROR] [%s] [%s] [%s] %s".intern
private val warningFormat = "[WARN] [%s] [%s] [%s] %s".intern
private val infoFormat = "[INFO] [%s] [%s] [%s] %s".intern
private val debugFormat = "[DEBUG] [%s] [%s] [%s] %s".intern
def timestamp = dateFormat.format(new Date)
def timestamp(): String = synchronized { dateFormat.format(new Date) } // SDF isn't threadsafe
def print(event: Any) {
event match {
case e: Error error(e)
case e: Warning warning(e)
case e: Info info(e)
case e: Debug debug(e)
case e warning(Warning(simpleName(this), this.getClass, "received unexpected event of class " + e.getClass + ": " + e))
}
def print(event: Any): Unit = event match {
case e: Error error(e)
case e: Warning warning(e)
case e: Info info(e)
case e: Debug debug(e)
case e warning(Warning(simpleName(this), this.getClass, "received unexpected event of class " + e.getClass + ": " + e))
}
def error(event: Error) = {
def error(event: Error): Unit = {
val f = if (event.cause == Error.NoCause) errorFormatWithoutCause else errorFormat
println(f.format(
timestamp,
@ -654,21 +674,21 @@ object Logging {
stackTraceFor(event.cause)))
}
def warning(event: Warning) =
def warning(event: Warning): Unit =
println(warningFormat.format(
timestamp,
event.thread.getName,
event.logSource,
event.message))
def info(event: Info) =
def info(event: Info): Unit =
println(infoFormat.format(
timestamp,
event.thread.getName,
event.logSource,
event.message))
def debug(event: Debug) =
def debug(event: Debug): Unit =
println(debugFormat.format(
timestamp,
event.thread.getName,
@ -689,8 +709,8 @@ object Logging {
override val toString = "StandardOutLogger"
override def !(message: Any)(implicit sender: ActorRef = null): Unit = print(message)
}
val StandardOutLogger = new StandardOutLogger
val StandardOutLoggerName = StandardOutLogger.getClass.getName
/**
* Actor wrapper around the standard output logger. If
@ -708,7 +728,7 @@ object Logging {
* Returns the StackTrace for the given Throwable as a String
*/
def stackTraceFor(e: Throwable): String = e match {
case null | Error.NoCause ""
case null | Error.NoCause | _: NoStackTrace ""
case other
val sw = new java.io.StringWriter
val pw = new java.io.PrintWriter(sw)
@ -752,51 +772,51 @@ trait LoggingAdapter {
* These actually implement the passing on of the messages to be logged.
* Will not be called if is...Enabled returned false.
*/
protected def notifyError(message: String)
protected def notifyError(cause: Throwable, message: String)
protected def notifyWarning(message: String)
protected def notifyInfo(message: String)
protected def notifyDebug(message: String)
protected def notifyError(message: String): Unit
protected def notifyError(cause: Throwable, message: String): Unit
protected def notifyWarning(message: String): Unit
protected def notifyInfo(message: String): Unit
protected def notifyDebug(message: String): Unit
/*
* The rest is just the widening of the API for the user's convenience.
*/
def error(cause: Throwable, message: String) { if (isErrorEnabled) notifyError(cause, message) }
def error(cause: Throwable, template: String, arg1: Any) { if (isErrorEnabled) notifyError(cause, format1(template, arg1)) }
def error(cause: Throwable, template: String, arg1: Any, arg2: Any) { if (isErrorEnabled) notifyError(cause, format(template, arg1, arg2)) }
def error(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any) { if (isErrorEnabled) notifyError(cause, format(template, arg1, arg2, arg3)) }
def error(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any) { if (isErrorEnabled) notifyError(cause, format(template, arg1, arg2, arg3, arg4)) }
def error(cause: Throwable, message: String): Unit = { if (isErrorEnabled) notifyError(cause, message) }
def error(cause: Throwable, template: String, arg1: Any): Unit = { if (isErrorEnabled) notifyError(cause, format1(template, arg1)) }
def error(cause: Throwable, template: String, arg1: Any, arg2: Any): Unit = { if (isErrorEnabled) notifyError(cause, format(template, arg1, arg2)) }
def error(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any): Unit = { if (isErrorEnabled) notifyError(cause, format(template, arg1, arg2, arg3)) }
def error(cause: Throwable, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = { if (isErrorEnabled) notifyError(cause, format(template, arg1, arg2, arg3, arg4)) }
def error(message: String) { if (isErrorEnabled) notifyError(message) }
def error(template: String, arg1: Any) { if (isErrorEnabled) notifyError(format1(template, arg1)) }
def error(template: String, arg1: Any, arg2: Any) { if (isErrorEnabled) notifyError(format(template, arg1, arg2)) }
def error(template: String, arg1: Any, arg2: Any, arg3: Any) { if (isErrorEnabled) notifyError(format(template, arg1, arg2, arg3)) }
def error(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any) { if (isErrorEnabled) notifyError(format(template, arg1, arg2, arg3, arg4)) }
def error(message: String): Unit = { if (isErrorEnabled) notifyError(message) }
def error(template: String, arg1: Any): Unit = { if (isErrorEnabled) notifyError(format1(template, arg1)) }
def error(template: String, arg1: Any, arg2: Any): Unit = { if (isErrorEnabled) notifyError(format(template, arg1, arg2)) }
def error(template: String, arg1: Any, arg2: Any, arg3: Any): Unit = { if (isErrorEnabled) notifyError(format(template, arg1, arg2, arg3)) }
def error(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = { if (isErrorEnabled) notifyError(format(template, arg1, arg2, arg3, arg4)) }
def warning(message: String) { if (isWarningEnabled) notifyWarning(message) }
def warning(template: String, arg1: Any) { if (isWarningEnabled) notifyWarning(format1(template, arg1)) }
def warning(template: String, arg1: Any, arg2: Any) { if (isWarningEnabled) notifyWarning(format(template, arg1, arg2)) }
def warning(template: String, arg1: Any, arg2: Any, arg3: Any) { if (isWarningEnabled) notifyWarning(format(template, arg1, arg2, arg3)) }
def warning(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any) { if (isWarningEnabled) notifyWarning(format(template, arg1, arg2, arg3, arg4)) }
def warning(message: String): Unit = { if (isWarningEnabled) notifyWarning(message) }
def warning(template: String, arg1: Any): Unit = { if (isWarningEnabled) notifyWarning(format1(template, arg1)) }
def warning(template: String, arg1: Any, arg2: Any): Unit = { if (isWarningEnabled) notifyWarning(format(template, arg1, arg2)) }
def warning(template: String, arg1: Any, arg2: Any, arg3: Any): Unit = { if (isWarningEnabled) notifyWarning(format(template, arg1, arg2, arg3)) }
def warning(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = { if (isWarningEnabled) notifyWarning(format(template, arg1, arg2, arg3, arg4)) }
def info(message: String) { if (isInfoEnabled) notifyInfo(message) }
def info(template: String, arg1: Any) { if (isInfoEnabled) notifyInfo(format1(template, arg1)) }
def info(template: String, arg1: Any, arg2: Any) { if (isInfoEnabled) notifyInfo(format(template, arg1, arg2)) }
def info(template: String, arg1: Any, arg2: Any, arg3: Any) { if (isInfoEnabled) notifyInfo(format(template, arg1, arg2, arg3)) }
def info(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any) { if (isInfoEnabled) notifyInfo(format(template, arg1, arg2, arg3, arg4)) }
def info(template: String, arg1: Any): Unit = { if (isInfoEnabled) notifyInfo(format1(template, arg1)) }
def info(template: String, arg1: Any, arg2: Any): Unit = { if (isInfoEnabled) notifyInfo(format(template, arg1, arg2)) }
def info(template: String, arg1: Any, arg2: Any, arg3: Any): Unit = { if (isInfoEnabled) notifyInfo(format(template, arg1, arg2, arg3)) }
def info(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = { if (isInfoEnabled) notifyInfo(format(template, arg1, arg2, arg3, arg4)) }
def debug(message: String) { if (isDebugEnabled) notifyDebug(message) }
def debug(template: String, arg1: Any) { if (isDebugEnabled) notifyDebug(format1(template, arg1)) }
def debug(template: String, arg1: Any, arg2: Any) { if (isDebugEnabled) notifyDebug(format(template, arg1, arg2)) }
def debug(template: String, arg1: Any, arg2: Any, arg3: Any) { if (isDebugEnabled) notifyDebug(format(template, arg1, arg2, arg3)) }
def debug(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any) { if (isDebugEnabled) notifyDebug(format(template, arg1, arg2, arg3, arg4)) }
def debug(template: String, arg1: Any): Unit = { if (isDebugEnabled) notifyDebug(format1(template, arg1)) }
def debug(template: String, arg1: Any, arg2: Any): Unit = { if (isDebugEnabled) notifyDebug(format(template, arg1, arg2)) }
def debug(template: String, arg1: Any, arg2: Any, arg3: Any): Unit = { if (isDebugEnabled) notifyDebug(format(template, arg1, arg2, arg3)) }
def debug(template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = { if (isDebugEnabled) notifyDebug(format(template, arg1, arg2, arg3, arg4)) }
def log(level: Logging.LogLevel, message: String) { if (isEnabled(level)) notifyLog(level, message) }
def log(level: Logging.LogLevel, template: String, arg1: Any) { if (isEnabled(level)) notifyLog(level, format1(template, arg1)) }
def log(level: Logging.LogLevel, template: String, arg1: Any, arg2: Any) { if (isEnabled(level)) notifyLog(level, format(template, arg1, arg2)) }
def log(level: Logging.LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any) { if (isEnabled(level)) notifyLog(level, format(template, arg1, arg2, arg3)) }
def log(level: Logging.LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any) { if (isEnabled(level)) notifyLog(level, format(template, arg1, arg2, arg3, arg4)) }
def log(level: Logging.LogLevel, template: String, arg1: Any): Unit = { if (isEnabled(level)) notifyLog(level, format1(template, arg1)) }
def log(level: Logging.LogLevel, template: String, arg1: Any, arg2: Any): Unit = { if (isEnabled(level)) notifyLog(level, format(template, arg1, arg2)) }
def log(level: Logging.LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any): Unit = { if (isEnabled(level)) notifyLog(level, format(template, arg1, arg2, arg3)) }
def log(level: Logging.LogLevel, template: String, arg1: Any, arg2: Any, arg3: Any, arg4: Any): Unit = { if (isEnabled(level)) notifyLog(level, format(template, arg1, arg2, arg3, arg4)) }
final def isEnabled(level: Logging.LogLevel): Boolean = level match {
case Logging.ErrorLevel isErrorEnabled
@ -812,14 +832,14 @@ trait LoggingAdapter {
case Logging.DebugLevel if (isDebugEnabled) notifyDebug(message)
}
private def format1(t: String, arg: Any) = arg match {
private def format1(t: String, arg: Any): String = arg match {
case a: Array[_] if !a.getClass.getComponentType.isPrimitive format(t, a: _*)
case a: Array[_] format(t, (a map (_.asInstanceOf[AnyRef]): _*))
case x format(t, x)
}
def format(t: String, arg: Any*) = {
val sb = new StringBuilder
def format(t: String, arg: Any*): String = {
val sb = new StringBuilder //FIXME add some decent size hint here
var p = 0
var rest = t
while (p < arg.length) {
@ -829,17 +849,15 @@ trait LoggingAdapter {
rest = ""
p = arg.length
} else {
sb.append(rest.substring(0, index))
sb.append(arg(p))
sb.append(rest.substring(0, index)).append(arg(p))
rest = rest.substring(index + 2)
p += 1
}
}
sb.append(rest)
sb.toString
sb.append(rest).toString
}
}
//FIXME DOCUMENT
class BusLogging(val bus: LoggingBus, val logSource: String, val logClass: Class[_]) extends LoggingAdapter {
import Logging._
@ -849,14 +867,9 @@ class BusLogging(val bus: LoggingBus, val logSource: String, val logClass: Class
def isInfoEnabled = bus.logLevel >= InfoLevel
def isDebugEnabled = bus.logLevel >= DebugLevel
protected def notifyError(message: String) { bus.publish(Error(logSource, logClass, message)) }
protected def notifyError(cause: Throwable, message: String) { bus.publish(Error(cause, logSource, logClass, message)) }
protected def notifyWarning(message: String) { bus.publish(Warning(logSource, logClass, message)) }
protected def notifyInfo(message: String) { bus.publish(Info(logSource, logClass, message)) }
protected def notifyDebug(message: String) { bus.publish(Debug(logSource, logClass, message)) }
protected def notifyError(message: String): Unit = bus.publish(Error(logSource, logClass, message))
protected def notifyError(cause: Throwable, message: String): Unit = bus.publish(Error(cause, logSource, logClass, message))
protected def notifyWarning(message: String): Unit = bus.publish(Warning(logSource, logClass, message))
protected def notifyInfo(message: String): Unit = bus.publish(Info(logSource, logClass, message))
protected def notifyDebug(message: String): Unit = bus.publish(Debug(logSource, logClass, message))
}

View file

@ -26,9 +26,7 @@ object LoggingReceive {
*/
def apply(r: Receive)(implicit context: ActorContext): Receive = r match {
case _: LoggingReceive r
case _
if (context.system.settings.AddLoggingReceive) new LoggingReceive(None, r)
else r
case _ if (context.system.settings.AddLoggingReceive) new LoggingReceive(None, r) else r
}
}
@ -37,7 +35,7 @@ object LoggingReceive {
* @param source the log source, if not defined the actor of the context will be used
*/
class LoggingReceive(source: Option[AnyRef], r: Receive)(implicit context: ActorContext) extends Receive {
def isDefinedAt(o: Any) = {
def isDefinedAt(o: Any): Boolean = {
val handled = r.isDefinedAt(o)
val (str, clazz) = LogSource.fromAnyRef(source getOrElse context.asInstanceOf[ActorCell].actor)
context.system.eventStream.publish(Debug(str, clazz, "received " + (if (handled) "handled" else "unhandled") + " message " + o))

View file

@ -24,28 +24,14 @@ trait Function2[T1, T2, R] {
* A Procedure is like a Function, but it doesn't produce a return value.
*/
trait Procedure[T] {
def apply(param: T)
}
/**
* A Procedure is like a Function, but it doesn't produce a return value.
*/
trait Procedure2[T1, T2] {
def apply(param: T1, param2: T2)
}
/**
* An executable piece of code that takes no parameters and doesn't return any value.
*/
trait SideEffect {
def apply()
def apply(param: T): Unit
}
/**
* An executable piece of code that takes no parameters and doesn't return any value.
*/
trait Effect {
def apply()
def apply(): Unit
}
/**
@ -67,9 +53,9 @@ sealed abstract class Option[A] extends java.lang.Iterable[A] {
def get: A
def isEmpty: Boolean
def isDefined = !isEmpty
def isDefined: Boolean = !isEmpty
def asScala: scala.Option[A]
def iterator = if (isEmpty) Iterator.empty else Iterator.single(get)
def iterator: java.util.Iterator[A] = if (isEmpty) Iterator.empty else Iterator.single(get)
}
object Option {
@ -102,18 +88,18 @@ object Option {
* <code>A</code>.
*/
final case class Some[A](v: A) extends Option[A] {
def get = v
def isEmpty = false
def asScala = scala.Some(v)
def get: A = v
def isEmpty: Boolean = false
def asScala: scala.Some[A] = scala.Some(v)
}
/**
* This case object represents non-existent values.
*/
private case object None extends Option[Nothing] {
def get = throw new NoSuchElementException("None.get")
def isEmpty = true
def asScala = scala.None
def get: Nothing = throw new NoSuchElementException("None.get")
def isEmpty: Boolean = true
def asScala: scala.None.type = scala.None
}
implicit def java2ScalaOption[A](o: Option[A]): scala.Option[A] = o.asScala

View file

@ -7,17 +7,12 @@ package akka.util
import java.util.concurrent.locks.{ ReentrantLock }
import java.util.concurrent.atomic.{ AtomicBoolean }
final class ReentrantGuard {
final val lock = new ReentrantLock
final class ReentrantGuard extends ReentrantLock {
@inline
final def withGuard[T](body: T): T = {
lock.lock
try {
body
} finally {
lock.unlock
}
lock()
try body finally unlock()
}
}
@ -104,19 +99,13 @@ class Switch(startAsOn: Boolean = false) {
* Executes the provided action and returns its value if the switch is on, waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def whileOnYield[T](action: T): Option[T] = synchronized {
if (switch.get) Some(action)
else None
}
def whileOnYield[T](action: T): Option[T] = synchronized { if (switch.get) Some(action) else None }
/**
* Executes the provided action and returns its value if the switch is off, waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def whileOffYield[T](action: T): Option[T] = synchronized {
if (!switch.get) Some(action)
else None
}
def whileOffYield[T](action: T): Option[T] = synchronized { if (!switch.get) Some(action) else None }
/**
* Executes the provided action and returns if the action was executed or not, if the switch is on, waiting for any pending changes to happen before (locking)
@ -144,9 +133,7 @@ class Switch(startAsOn: Boolean = false) {
* Executes the provided callbacks depending on if the switch is either on or off waiting for any pending changes to happen before (locking)
* Be careful of longrunning or blocking within the provided action as it can lead to deadlocks or bad performance
*/
def fold[T](on: T)(off: T) = synchronized {
if (switch.get) on else off
}
def fold[T](on: T)(off: T): T = synchronized { if (switch.get) on else off }
/**
* Executes the given code while holding this switchs lock, i.e. protected from concurrent modification of the switch status.