From 5eba9fceef884b16c8764a78d0d8bb274dfbc830 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Fri, 18 May 2012 13:37:26 +0200 Subject: [PATCH] Saving the planet and shufflin' --- .../scala/akka/event/EventStreamSpec.scala | 2 +- .../main/scala/akka/actor/UntypedActor.scala | 12 +- .../scala/akka/dispatch/Dispatchers.scala | 6 +- .../main/scala/akka/dispatch/Mailbox.scala | 56 +++++- .../main/scala/akka/event/DeathWatch.scala | 2 +- .../src/main/scala/akka/event/EventBus.scala | 15 +- .../src/main/scala/akka/event/Logging.scala | 167 ++++++++++-------- .../scala/akka/event/LoggingReceive.scala | 6 +- .../src/main/scala/akka/japi/JavaAPI.scala | 34 ++-- .../src/main/scala/akka/util/LockUtil.scala | 25 +-- 10 files changed, 177 insertions(+), 148 deletions(-) diff --git a/akka-actor-tests/src/test/scala/akka/event/EventStreamSpec.scala b/akka-actor-tests/src/test/scala/akka/event/EventStreamSpec.scala index d2497c4a69..a8cd32f5d3 100644 --- a/akka-actor-tests/src/test/scala/akka/event/EventStreamSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/event/EventStreamSpec.scala @@ -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 { diff --git a/akka-actor/src/main/scala/akka/actor/UntypedActor.scala b/akka-actor/src/main/scala/akka/actor/UntypedActor.scala index a5ebeb851c..c56a2a0167 100644 --- a/akka-actor/src/main/scala/akka/actor/UntypedActor.scala +++ b/akka-actor/src/main/scala/akka/actor/UntypedActor.scala @@ -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) } } /** diff --git a/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala b/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala index 54173b8460..9fae624e66 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala @@ -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. diff --git a/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala b/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala index 2e3a98e8d9..1bb882d497 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala @@ -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"), diff --git a/akka-actor/src/main/scala/akka/event/DeathWatch.scala b/akka-actor/src/main/scala/akka/event/DeathWatch.scala index 7469f6609f..8bf6935619 100644 --- a/akka-actor/src/main/scala/akka/event/DeathWatch.scala +++ b/akka-actor/src/main/scala/akka/event/DeathWatch.scala @@ -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 diff --git a/akka-actor/src/main/scala/akka/event/EventBus.scala b/akka-actor/src/main/scala/akka/event/EventBus.scala index 2dd22b3b54..6a5cc67cc4 100644 --- a/akka-actor/src/main/scala/akka/event/EventBus.scala +++ b/akka-actor/src/main/scala/akka/event/EventBus.scala @@ -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) diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala index ac31b133b3..1230756517 100644 --- a/akka-actor/src/main/scala/akka/event/Logging.scala +++ b/akka-actor/src/main/scala/akka/event/Logging.scala @@ -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 system’s event stream and include the system’s 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)) } diff --git a/akka-actor/src/main/scala/akka/event/LoggingReceive.scala b/akka-actor/src/main/scala/akka/event/LoggingReceive.scala index 452b2b6b19..337815eed1 100644 --- a/akka-actor/src/main/scala/akka/event/LoggingReceive.scala +++ b/akka-actor/src/main/scala/akka/event/LoggingReceive.scala @@ -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)) diff --git a/akka-actor/src/main/scala/akka/japi/JavaAPI.scala b/akka-actor/src/main/scala/akka/japi/JavaAPI.scala index 47ce667759..5bd38ad52a 100644 --- a/akka-actor/src/main/scala/akka/japi/JavaAPI.scala +++ b/akka-actor/src/main/scala/akka/japi/JavaAPI.scala @@ -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 { * A. */ 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 diff --git a/akka-actor/src/main/scala/akka/util/LockUtil.scala b/akka-actor/src/main/scala/akka/util/LockUtil.scala index c3295d4b52..14c787d3f6 100644 --- a/akka-actor/src/main/scala/akka/util/LockUtil.scala +++ b/akka-actor/src/main/scala/akka/util/LockUtil.scala @@ -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 switch’s lock, i.e. protected from concurrent modification of the switch status.