Merge branch 'wip-1854-fix-restart-∂π'
This commit is contained in:
commit
18cd7f8d5f
7 changed files with 80 additions and 17 deletions
|
|
@ -60,5 +60,22 @@ class SupervisorMiscSpec extends AkkaSpec(SupervisorMiscSpec.config) with Defaul
|
|||
assert(Await.result(actor4 ? "status", timeout.duration) == "OK", "actor4 is shutdown")
|
||||
}
|
||||
}
|
||||
|
||||
"be able to create named children in its constructor" in {
|
||||
val a = system.actorOf(Props(new Actor {
|
||||
context.actorOf(Props.empty, "bob")
|
||||
def receive = {
|
||||
case x: Exception ⇒ throw x
|
||||
}
|
||||
override def preStart(): Unit = testActor ! "preStart"
|
||||
}))
|
||||
val m = "weird message"
|
||||
EventFilter[Exception](m, occurrences = 1) intercept {
|
||||
a ! new Exception(m)
|
||||
}
|
||||
expectMsg("preStart")
|
||||
expectMsg("preStart")
|
||||
a.isTerminated must be(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,7 +389,6 @@ private[akka] class ActorCell(
|
|||
def recreate(cause: Throwable): Unit = try {
|
||||
val failedActor = actor
|
||||
if (system.settings.DebugLifecycle) system.eventStream.publish(Debug(self.path.toString, clazz(failedActor), "restarting"))
|
||||
val freshActor = newActor()
|
||||
if (failedActor ne null) {
|
||||
val c = currentMessage //One read only plz
|
||||
try {
|
||||
|
|
@ -398,7 +397,8 @@ private[akka] class ActorCell(
|
|||
clearActorFields()
|
||||
}
|
||||
}
|
||||
actor = freshActor // assign it here so if preStart fails, we can null out the sef-refs next call
|
||||
val freshActor = newActor() // this must happen after failedActor.preRestart (to scrap those children)
|
||||
actor = freshActor // this must happen before postRestart has a chance to fail
|
||||
freshActor.postRestart(cause)
|
||||
if (system.settings.DebugLifecycle) system.eventStream.publish(Debug(self.path.toString, clazz(freshActor), "restarted"))
|
||||
|
||||
|
|
|
|||
|
|
@ -734,37 +734,37 @@ trait LoggingAdapter {
|
|||
*/
|
||||
|
||||
def error(cause: Throwable, message: String) { if (isErrorEnabled) notifyError(cause, message) }
|
||||
def error(cause: Throwable, template: String, arg1: Any) { if (isErrorEnabled) notifyError(cause, format(template, arg1)) }
|
||||
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(message: String) { if (isErrorEnabled) notifyError(message) }
|
||||
def error(template: String, arg1: Any) { if (isErrorEnabled) notifyError(format(template, arg1)) }
|
||||
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 warning(message: String) { if (isWarningEnabled) notifyWarning(message) }
|
||||
def warning(template: String, arg1: Any) { if (isWarningEnabled) notifyWarning(format(template, arg1)) }
|
||||
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 info(message: String) { if (isInfoEnabled) notifyInfo(message) }
|
||||
def info(template: String, arg1: Any) { if (isInfoEnabled) notifyInfo(format(template, arg1)) }
|
||||
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 debug(message: String) { if (isDebugEnabled) notifyDebug(message) }
|
||||
def debug(template: String, arg1: Any) { if (isDebugEnabled) notifyDebug(format(template, arg1)) }
|
||||
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 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, format(template, arg1)) }
|
||||
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)) }
|
||||
|
|
@ -783,16 +783,28 @@ trait LoggingAdapter {
|
|||
case Logging.DebugLevel ⇒ if (isDebugEnabled) notifyDebug(message)
|
||||
}
|
||||
|
||||
private def format1(t: String, arg: Any) = 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
|
||||
var p = 0
|
||||
var rest = t
|
||||
while (p < arg.length) {
|
||||
val index = rest.indexOf("{}")
|
||||
sb.append(rest.substring(0, index))
|
||||
sb.append(arg(p))
|
||||
rest = rest.substring(index + 2)
|
||||
p += 1
|
||||
if (index == -1) {
|
||||
sb.append(rest).append(" WARNING arguments left: ").append(arg.length - p)
|
||||
rest = ""
|
||||
p = arg.length
|
||||
} else {
|
||||
sb.append(rest.substring(0, index))
|
||||
sb.append(arg(p))
|
||||
rest = rest.substring(index + 2)
|
||||
p += 1
|
||||
}
|
||||
}
|
||||
sb.append(rest)
|
||||
sb.toString
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import akka.actor.DeadLetter;
|
|||
//#imports-deadletter
|
||||
|
||||
public class LoggingDocTestBase {
|
||||
|
||||
|
||||
@Test
|
||||
public void useLoggingActor() {
|
||||
ActorSystem system = ActorSystem.create("MySystem");
|
||||
|
|
@ -55,6 +55,16 @@ public class LoggingDocTestBase {
|
|||
//#deadletters
|
||||
system.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void demonstrateMultipleArgs() {
|
||||
final ActorSystem system = ActorSystem.create("multiArg");
|
||||
//#array
|
||||
final Object[] args = new Object[] { "The", "brown", "fox", "jumps", 42 };
|
||||
system.log().debug("five parameters: {}, {}, {}, {}, {}", args);
|
||||
//#array
|
||||
system.shutdown();
|
||||
}
|
||||
|
||||
//#my-actor
|
||||
class MyActor extends UntypedActor {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ object is translated to a String according to the following rules:
|
|||
* in case of a class an approximation of its simpleName
|
||||
* and in all other cases the simpleName of its class
|
||||
|
||||
The log message may contain argument placeholders ``{}``, which will be substituted if the log level
|
||||
is enabled.
|
||||
The log message may contain argument placeholders ``{}``, which will be
|
||||
substituted if the log level is enabled. Giving more arguments as there are
|
||||
placeholders results in a warning being appended to the log statement (i.e. on
|
||||
the same line with the same severity). You may pass a Java array as the only
|
||||
substitution argument to have its elements be treated individually:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocTestBase.java#array
|
||||
|
||||
The Java :class:`Class` of the log source is also included in the generated
|
||||
:class:`LogEvent`. In case of a simple string this is replaced with a “marker”
|
||||
|
|
|
|||
|
|
@ -89,4 +89,11 @@ class LoggingDocSpec extends AkkaSpec {
|
|||
//#deadletters
|
||||
}
|
||||
|
||||
"demonstrate logging more arguments" in {
|
||||
//#array
|
||||
val args = Array("The", "brown", "fox", "jumps", 42)
|
||||
system.log.debug("five parameters: {}, {}, {}, {}, {}", args)
|
||||
//#array
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,20 @@ The source object is translated to a String according to the following rules:
|
|||
* and in all other cases a compile error occurs unless and implicit
|
||||
:class:`LogSource[T]` is in scope for the type in question.
|
||||
|
||||
The log message may contain argument placeholders ``{}``, which will be substituted if the log level
|
||||
is enabled.
|
||||
The log message may contain argument placeholders ``{}``, which will be
|
||||
substituted if the log level is enabled. Giving more arguments as there are
|
||||
placeholders results in a warning being appended to the log statement (i.e. on
|
||||
the same line with the same severity). You may pass a Java array as the only
|
||||
substitution argument to have its elements be treated individually:
|
||||
|
||||
.. includecode:: code/akka/docs/event/LoggingDocSpec.scala#array
|
||||
|
||||
The Java :class:`Class` of the log source is also included in the generated
|
||||
:class:`LogEvent`. In case of a simple string this is replaced with a “marker”
|
||||
class :class:`akka.event.DummyClassForStringSources` in order to allow special
|
||||
treatment of this case, e.g. in the SLF4J event listener which will then use
|
||||
the string instead of the class’ name for looking up the logger instance to
|
||||
use.
|
||||
|
||||
Auxiliary logging options
|
||||
-------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue