Repository: reef
Updated Branches:
refs/heads/master 9ce210313 -> 6f482d508
[REEF-1432] Validate Context Start failure => FailedContext Event
This addressed the issue by
* Adding a test to verify that an Exception in ContextStartHandler
causes a FailedContext if the Context has a parent
and a FailedEvaluator otherwise.
* Making changes in ContextManager and ContextRuntime to ensure
that the Exception is properly propagated to the Driver.
* Adding ContextException, ContextStartHandlerException, and
have ContextClientCodeException inherit ContextException.
JIRA:
[REEF-1432](https://issues.apache.org/jira/browse/REEF-1432)
Pull request:
This closes #1050
Project: http://git-wip-us.apache.org/repos/asf/reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/6f482d50
Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/6f482d50
Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/6f482d50
Branch: refs/heads/master
Commit: 6f482d50801e3ba2d865c0bbcebb88f27644a384
Parents: 9ce2103
Author: Andrew Chung <[email protected]>
Authored: Wed Jun 22 13:55:26 2016 -0700
Committer: Mariia Mykhailova <[email protected]>
Committed: Thu Jun 30 11:02:15 2016 -0700
----------------------------------------------------------------------
.../Org.Apache.REEF.Common.csproj | 2 +
.../Context/ContextClientCodeException.cs | 19 +-
.../Evaluator/Context/ContextException.cs | 46 ++++
.../Runtime/Evaluator/Context/ContextManager.cs | 73 +++---
.../Runtime/Evaluator/Context/ContextRuntime.cs | 76 ++++---
.../Context/ContextStartHandlerException.cs | 34 +++
.../Evaluator/Context/RootContextLauncher.cs | 1 -
.../Runtime/Evaluator/EvaluatorRuntime.cs | 5 +
.../Evaluator/Task/TaskStartHandlerException.cs | 3 +
.../Exceptions/TestSerializableException.cs | 2 +-
.../Failure/User/ContextStartExceptionTest.cs | 222 +++++++++++++++++++
.../Org.Apache.REEF.Tests.csproj | 1 +
12 files changed, 403 insertions(+), 81 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
index 3582f00..d438ad1 100644
--- a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
+++ b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj
@@ -142,9 +142,11 @@ under the License.
<Compile Include="Files\REEFFileNames.cs" />
<Compile Include="Runtime\Evaluator\Constants.cs" />
<Compile Include="Runtime\Evaluator\Context\ContextClientCodeException.cs"
/>
+ <Compile Include="Runtime\Evaluator\Context\ContextException.cs" />
<Compile Include="Runtime\Evaluator\Context\ContextLifeCycle.cs" />
<Compile Include="Runtime\Evaluator\Context\ContextManager.cs" />
<Compile Include="Runtime\Evaluator\Context\ContextRuntime.cs" />
+ <Compile
Include="Runtime\Evaluator\Context\ContextStartHandlerException.cs" />
<Compile Include="Runtime\Evaluator\Context\ContextStartImpl.cs" />
<Compile Include="Runtime\Evaluator\Context\ContextStopImpl.cs" />
<Compile Include="Runtime\Evaluator\Context\RootContextLauncher.cs" />
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextClientCodeException.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextClientCodeException.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextClientCodeException.cs
index a6f9b74..df841d2 100644
---
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextClientCodeException.cs
+++
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextClientCodeException.cs
@@ -20,11 +20,8 @@ using Org.Apache.REEF.Utilities;
namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
{
- internal sealed class ContextClientCodeException : Exception
+ internal sealed class ContextClientCodeException : ContextException
{
- private readonly string _contextId;
- private readonly Optional<string> _parentId;
-
/// <summary>
/// construct the exception that caused the error
/// </summary>
@@ -37,20 +34,8 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
Optional<string> parentId,
string message,
Exception cause)
- : base("Failure in context '" + contextId + "': " + message, cause)
- {
- _contextId = contextId;
- _parentId = parentId;
- }
-
- public string ContextId
- {
- get { return _contextId; }
- }
-
- public Optional<string> ParentId
+ : base(contextId, parentId, "Failure in context '" + contextId +
"': " + message, cause)
{
- get { return _parentId; }
}
}
}
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextException.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextException.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextException.cs
new file mode 100644
index 0000000..4771e73
--- /dev/null
+++
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextException.cs
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using Org.Apache.REEF.Utilities;
+
+namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
+{
+ internal abstract class ContextException : Exception
+ {
+ private readonly string _contextId;
+ private readonly Optional<string> _parentId;
+
+ internal ContextException(
+ string contextId, Optional<string> parentId, string message,
Exception inner) :
+ base(message, inner)
+ {
+ _contextId = contextId;
+ _parentId = parentId;
+ }
+
+ internal string ContextId
+ {
+ get { return _contextId; }
+ }
+
+ internal Optional<string> ParentId
+ {
+ get { return _parentId; }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextManager.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextManager.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextManager.cs
index 7f9e846..28d4e06 100644
--- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextManager.cs
+++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextManager.cs
@@ -72,7 +72,7 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
catch (TaskClientCodeException e)
{
Utilities.Diagnostics.Exceptions.Caught(e,
Level.Error, "Exception when trying to start a task.", LOGGER);
- HandleTaskException(e);
+ HandleTaskInitializationException(e);
}
}
}
@@ -100,13 +100,16 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
byte[] message = controlMessage.task_message;
if (controlMessage.add_context != null &&
controlMessage.remove_context != null)
{
- Utilities.Diagnostics.Exceptions.Throw(new
InvalidOperationException("Received a message with both add and remove context.
This is unsupported."), LOGGER);
+ Utilities.Diagnostics.Exceptions.Throw(
+ new InvalidOperationException(
+ "Received a message with both add and remove
context. This is unsupported."),
+ LOGGER);
}
if (controlMessage.add_context != null)
{
LOGGER.Log(Level.Info, "AddContext");
AddContext(controlMessage.add_context);
-
+
// support submitContextAndTask()
if (controlMessage.start_task != null)
{
@@ -123,7 +126,9 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
}
else if (controlMessage.remove_context != null)
{
- LOGGER.Log(Level.Info,
string.Format(CultureInfo.InvariantCulture, "RemoveContext with id {0}",
controlMessage.remove_context.context_id));
+ LOGGER.Log(Level.Info,
+ "RemoveContext with id {0}",
+ controlMessage.remove_context.context_id);
RemoveContext(controlMessage.remove_context.context_id);
}
else if (controlMessage.start_task != null)
@@ -164,7 +169,8 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
{
if (_topContext != null)
{
- context =
_topContext.GetContextStack().FirstOrDefault(ctx =>
ctx.Id.Equals(contextMessageProto.context_id));
+ context = _topContext.GetContextStack()
+ .FirstOrDefault(ctx =>
ctx.Id.Equals(contextMessageProto.context_id));
}
}
@@ -174,23 +180,33 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
}
else
{
- var e = new
InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Sent
message to unknown context {0}", contextMessageProto.context_id));
+ var e = new InvalidOperationException(
+ string.Format(CultureInfo.InvariantCulture,
+ "Sent message to unknown context {0}",
+ contextMessageProto.context_id));
Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
}
}
else
{
- InvalidOperationException e = new
InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unknown
task control message: {0}", controlMessage.ToString()));
+ InvalidOperationException e = new
InvalidOperationException(
+ string.Format(CultureInfo.InvariantCulture,
+ "Unknown task control message: {0}",
+ controlMessage));
Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
- }
+ }
}
catch (TaskClientCodeException e)
{
- HandleTaskException(e);
+ HandleTaskInitializationException(e);
}
catch (ContextClientCodeException e)
{
- HandleContextException(e);
+ HandleContextException(e, e.ContextId, e.ParentId);
+ }
+ catch (ContextException e)
+ {
+ HandleContextException(e.InnerException, e.ContextId,
e.ParentId);
}
}
@@ -344,7 +360,7 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
/// THIS ASSUMES THAT IT IS CALLED ON A THREAD HOLDING THE LOCK ON
THE HeartBeatManager
/// </summary>
/// <param name="e"></param>
- private void HandleTaskException(TaskClientCodeException e)
+ private void HandleTaskInitializationException(TaskClientCodeException
e)
{
byte[] error;
try
@@ -377,26 +393,27 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
_heartBeatManager.OnNext(taskStatus);
}
- /// <summary>
- /// THIS ASSUMES THAT IT IS CALLED ON A THREAD HOLDING THE LOCK ON THE
HeartBeatManager
- /// </summary>
- /// <param name="e"></param>
- private void HandleContextException(ContextClientCodeException e)
+ private void HandleContextException(Exception e, string contextId,
Optional<string> parentContextId)
{
- LOGGER.Log(Level.Error, "ContextClientCodeException", e);
- byte[] exception = ByteUtilities.StringToByteArrays(e.ToString());
- ContextStatusProto contextStatusProto = new ContextStatusProto()
+ lock (_heartBeatManager)
{
- context_id = e.ContextId,
- context_state = ContextStatusProto.State.FAIL,
- error = exception
- };
- if (e.ParentId.IsPresent())
- {
- contextStatusProto.parent_id = e.ParentId.Value;
+ LOGGER.Log(Level.Warning, "ContextException", e);
+ byte[] exception =
ByteUtilities.StringToByteArrays(e.ToString());
+ var contextStatusProto = new ContextStatusProto
+ {
+ context_id = contextId,
+ context_state = ContextStatusProto.State.FAIL,
+ error = exception
+ };
+
+ if (parentContextId.IsPresent())
+ {
+ contextStatusProto.parent_id = parentContextId.Value;
+ }
+
+ LOGGER.Log(Level.Error, "Sending Heartbeat for a failed
context: {0}", contextStatusProto);
+ _heartBeatManager.OnNext(contextStatusProto);
}
- LOGGER.Log(Level.Error, "Sending Heartbeat for a failed context:
{0}", contextStatusProto);
- _heartBeatManager.OnNext(contextStatusProto);
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextRuntime.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextRuntime.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextRuntime.cs
index eced5e2..953aa54 100644
--- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextRuntime.cs
+++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextRuntime.cs
@@ -137,7 +137,22 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
_contextInjector =
serviceInjector.ForkInjector(contextConfiguration);
_contextLifeCycle =
_contextInjector.GetInstance<ContextLifeCycle>();
_parentContext = parentContext;
- _contextLifeCycle.Start();
+
+ try
+ {
+ _contextLifeCycle.Start();
+ }
+ catch (Exception e)
+ {
+ const string message = "Encountered Exception in
ContextStartHandler.";
+ if (ParentContext.IsPresent())
+ {
+ throw new ContextStartHandlerException(
+ Id, Optional<string>.Of(ParentContext.Value.Id),
message, e);
+ }
+
+ throw new ContextStartHandlerException(Id,
Optional<string>.Empty(), message, e);
+ }
}
public string Id
@@ -199,28 +214,33 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
/// <param name="childContextConfiguration">the new context's context
(local) Configuration.</param>
/// <param name="childServiceConfiguration">the new context's service
Configuration.</param>
/// <returns>a child context.</returns>
- public ContextRuntime SpawnChildContext(IConfiguration
childContextConfiguration, IConfiguration childServiceConfiguration)
+ public ContextRuntime SpawnChildContext(
+ IConfiguration childContextConfiguration,
+ IConfiguration childServiceConfiguration = null)
{
lock (_contextLifeCycle)
{
if (_task.IsPresent())
{
- var message =
- string.Format(CultureInfo.InvariantCulture,
"Attempting to spawn a child context when an Task with id '{0}' is running",
_task.Value.TaskId);
-
- var e = new InvalidOperationException(message);
- Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+ throw new InvalidOperationException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Attempting to spawn a child context when an Task
with id '{0}' is running",
+ _task.Value.TaskId));
}
AssertChildContextNotPresent("Attempting to instantiate a
child context on a context that is not the topmost active context.");
try
{
- var childServiceInjector =
_serviceInjector.ForkInjector(childServiceConfiguration);
- var childContext = new
ContextRuntime(childServiceInjector, childContextConfiguration,
Optional<ContextRuntime>.Of(this));
+ var childServiceInjector = childServiceConfiguration ==
null
+ ? _serviceInjector.ForkInjector()
+ :
_serviceInjector.ForkInjector(childServiceConfiguration);
- _childContext = Optional<ContextRuntime>.Of(childContext);
- return childContext;
+ _childContext = Optional<ContextRuntime>.Of(
+ new ContextRuntime(childServiceInjector,
childContextConfiguration, Optional<ContextRuntime>.Of(this)));
+
+ return _childContext.Value;
}
catch (Exception e)
{
@@ -243,32 +263,20 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
}
}
- /// <summary>
- /// Spawns a new context without services of its own.
- /// The new context will have a serviceInjector that is created by
forking the one in this object. The
- /// contextConfiguration is used to fork the contextInjector from that
new serviceInjector.
- /// </summary>
- /// <param name="childContextConfiguration">the new context's context
(local) Configuration.</param>
- /// <returns> a child context.</returns>
- public ContextRuntime SpawnChildContext(IConfiguration
childContextConfiguration)
+ private static string GetChildContextId(IConfiguration
childContextConfiguration)
{
- lock (_contextLifeCycle)
+ var contextId = string.Empty;
+ try
{
- if (_task.IsPresent())
- {
- var message =
- string.Format(CultureInfo.InvariantCulture,
"Attempting to spawn a child context when an Task with id '{0}' is running",
_task.Value.TaskId);
-
- var e = new InvalidOperationException(message);
- Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
- }
-
- AssertChildContextNotPresent("Attempting to instantiate a
child context on a context that is not the topmost active context.");
-
- IInjector childServiceInjector =
_serviceInjector.ForkInjector();
- _childContext = Optional<ContextRuntime>.Of(new
ContextRuntime(childServiceInjector, childContextConfiguration,
Optional<ContextRuntime>.Of(this)));
- return _childContext.Value;
+ var injector =
TangFactory.GetTang().NewInjector(childContextConfiguration);
+ contextId =
injector.GetNamedInstance<ContextConfigurationOptions.ContextIdentifier,
string>();
}
+ catch (InjectionException)
+ {
+ LOGGER.Log(Level.Error, "Unable to get Context ID from child
ContextConfiguration. Using empty string.");
+ }
+
+ return contextId;
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextStartHandlerException.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextStartHandlerException.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextStartHandlerException.cs
new file mode 100644
index 0000000..594d12d
--- /dev/null
+++
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/ContextStartHandlerException.cs
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using Org.Apache.REEF.Utilities;
+
+namespace Org.Apache.REEF.Common.Runtime.Evaluator.Context
+{
+ /// <summary>
+ /// Exception that is thrown when the ContextStartHandler encounters an
Exception.
+ /// </summary>
+ internal sealed class ContextStartHandlerException : ContextException
+ {
+ internal ContextStartHandlerException(
+ string contextId, Optional<string> parentId, string message,
Exception inner) :
+ base(contextId, parentId, message, inner)
+ {
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/RootContextLauncher.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/RootContextLauncher.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/RootContextLauncher.cs
index 165bc4d..ef8795d 100644
---
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/RootContextLauncher.cs
+++
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Context/RootContextLauncher.cs
@@ -22,7 +22,6 @@ using Org.Apache.REEF.Common.Runtime.Evaluator.Utils;
using Org.Apache.REEF.Common.Services;
using Org.Apache.REEF.Tang.Annotations;
using Org.Apache.REEF.Tang.Formats;
-using Org.Apache.REEF.Tang.Implementations.Tang;
using Org.Apache.REEF.Tang.Interface;
using Org.Apache.REEF.Utilities;
using Org.Apache.REEF.Utilities.Logging;
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
index 80f0ce5..c1448d1 100644
--- a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
+++ b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/EvaluatorRuntime.cs
@@ -182,6 +182,11 @@ namespace Org.Apache.REEF.Common.Runtime.Evaluator
_contextManager.Start();
_heartBeatManager.OnNext();
}
+ catch (ContextException e)
+ {
+ Utilities.Diagnostics.Exceptions.Caught(e, Level.Error,
Logger);
+ OnException(e.InnerException);
+ }
catch (Exception e)
{
Utilities.Diagnostics.Exceptions.Caught(e, Level.Error,
Logger);
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartHandlerException.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartHandlerException.cs
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartHandlerException.cs
index 07e8b10..2e83179 100644
---
a/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartHandlerException.cs
+++
b/lang/cs/Org.Apache.REEF.Common/Runtime/Evaluator/Task/TaskStartHandlerException.cs
@@ -19,6 +19,9 @@ using System;
namespace Org.Apache.REEF.Common.Runtime.Evaluator.Task
{
+ /// <summary>
+ /// Exception that is thrown when the TaskStartHandler encounters an
Exception.
+ /// </summary>
internal sealed class TaskStartHandlerException : Exception
{
internal TaskStartHandlerException(string message, Exception inner) :
base(message, inner)
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs
b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs
index ee9840e..cb9d6bb 100644
---
a/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs
+++
b/lang/cs/Org.Apache.REEF.Tests/Functional/Bridge/Exceptions/TestSerializableException.cs
@@ -28,7 +28,7 @@ namespace Org.Apache.REEF.Tests.Functional.Bridge.Exceptions
{
}
- public TestSerializableException(SerializationInfo info,
StreamingContext context)
+ private TestSerializableException(SerializationInfo info,
StreamingContext context)
: base(info, context)
{
}
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/ContextStartExceptionTest.cs
----------------------------------------------------------------------
diff --git
a/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/ContextStartExceptionTest.cs
b/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/ContextStartExceptionTest.cs
new file mode 100644
index 0000000..931f3c2
--- /dev/null
+++
b/lang/cs/Org.Apache.REEF.Tests/Functional/Failure/User/ContextStartExceptionTest.cs
@@ -0,0 +1,222 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using Org.Apache.REEF.Common.Context;
+using Org.Apache.REEF.Common.Events;
+using Org.Apache.REEF.Common.Tasks;
+using Org.Apache.REEF.Driver;
+using Org.Apache.REEF.Driver.Context;
+using Org.Apache.REEF.Driver.Evaluator;
+using Org.Apache.REEF.Driver.Task;
+using Org.Apache.REEF.Tang.Annotations;
+using Org.Apache.REEF.Tang.Interface;
+using Org.Apache.REEF.Tang.Util;
+using Org.Apache.REEF.Tests.Functional.Bridge.Exceptions;
+using Org.Apache.REEF.Utilities.Logging;
+using Xunit;
+
+namespace Org.Apache.REEF.Tests.Functional.Failure.User
+{
+ [Collection("FunctionalTests")]
+ public sealed class ContextStartExceptionTest : ReefFunctionalTest
+ {
+ private static readonly Logger Logger =
Logger.GetLogger(typeof(ContextStartExceptionTest));
+
+ private static readonly string ExpectedException = "ExpectedException";
+ private static readonly string FailEvaluatorContextId =
"FailEvaluatorContextId";
+ private static readonly string ContextId0 = "ContextId0";
+ private static readonly string ContextId1 = "ContextId1";
+ private static readonly string TaskId = "TaskId";
+ private static readonly string CompletedTaskReceived =
"CompletedTaskReceived";
+ private static readonly string FailedContextReceived =
"FailedContextReceived";
+ private static readonly string FailedEvaluatorReceived =
"FailedEvaluatorReceived";
+
+ [Fact]
+ [Trait("Priority", "1")]
+ [Trait("Category", "FunctionalGated")]
+ [Trait("Description", "Test throwing an Exception in
ContextStartHandler should cause the Driver to receive a ContextFailed event." +
+ "In the case of the Root Context, the Driver
should receive a FailedEvaluator event.")]
+ public void TestContextStartException()
+ {
+ string testFolder = DefaultRuntimeFolder + TestId;
+ TestRun(
+ DriverConfiguration.ConfigurationModule
+ .Set(DriverConfiguration.OnDriverStarted,
GenericType<ContextStartExceptionDriver>.Class)
+ .Set(DriverConfiguration.OnEvaluatorAllocated,
GenericType<ContextStartExceptionDriver>.Class)
+ .Set(DriverConfiguration.OnEvaluatorFailed,
GenericType<ContextStartExceptionDriver>.Class)
+ .Set(DriverConfiguration.OnContextActive,
GenericType<ContextStartExceptionDriver>.Class)
+ .Set(DriverConfiguration.OnContextFailed,
GenericType<ContextStartExceptionDriver>.Class)
+ .Set(DriverConfiguration.OnTaskCompleted,
GenericType<ContextStartExceptionDriver>.Class)
+ .Build(),
+ typeof(ContextStartExceptionDriver), 1,
"ContextStartExceptionTest", "local", testFolder);
+
+ ValidateSuccessForLocalRuntime(numberOfContextsToClose: 1,
numberOfTasksToFail: 0, numberOfEvaluatorsToFail: 1, testFolder: testFolder);
+ var driverMessages = new[]
+ {
+ CompletedTaskReceived,
+ FailedContextReceived,
+ FailedEvaluatorReceived
+ };
+
+ ValidateMessagesSuccessfullyLoggedForDriver(driverMessages,
testFolder);
+ CleanUp(testFolder);
+ }
+
+ private sealed class ContextStartExceptionDriver :
+ IObserver<IDriverStarted>,
+ IObserver<IAllocatedEvaluator>,
+ IObserver<IActiveContext>,
+ IObserver<IFailedContext>,
+ IObserver<IFailedEvaluator>,
+ IObserver<ICompletedTask>
+ {
+ private readonly IEvaluatorRequestor _requestor;
+ private readonly object _lock = new object();
+ private bool _shouldSubmitFailEvaluatorContext = true;
+
+ [Inject]
+ private ContextStartExceptionDriver(IEvaluatorRequestor requestor)
+ {
+ _requestor = requestor;
+ }
+
+ public void OnNext(IDriverStarted value)
+ {
+
_requestor.Submit(_requestor.NewBuilder().SetNumber(2).Build());
+ }
+
+ public void OnNext(IAllocatedEvaluator value)
+ {
+ lock (_lock)
+ {
+ if (_shouldSubmitFailEvaluatorContext)
+ {
+ value.SubmitContext(
+
GetContextStartExceptionContextConfiguration(FailEvaluatorContextId));
+ _shouldSubmitFailEvaluatorContext = false;
+ }
+ else
+ {
+ value.SubmitContext(
+ ContextConfiguration.ConfigurationModule
+ .Set(ContextConfiguration.Identifier,
ContextId0)
+ .Build());
+ }
+ }
+ }
+
+ public void OnNext(IFailedContext value)
+ {
+ Assert.Equal(ContextId1, value.Id);
+ Assert.True(value.ParentContext.IsPresent());
+ Assert.Equal(ContextId0, value.ParentContext.Value.Id);
+
+ // TODO[JIRA REEF-1468]: Validate that Exception is properly
serialized.
+ Logger.Log(Level.Info, FailedContextReceived);
+
+ value.ParentContext.Value.SubmitTask(
+ TaskConfiguration.ConfigurationModule
+ .Set(TaskConfiguration.Identifier, TaskId)
+ .Set(TaskConfiguration.Task,
GenericType<ContextStartExceptionTask>.Class)
+ .Build());
+ }
+
+ public void OnNext(IFailedEvaluator value)
+ {
+ // We should not have any failed contexts since the context
has never become active.
+ Assert.Equal(0, value.FailedContexts.Count);
+ Assert.NotNull(value.EvaluatorException.InnerException);
+ Assert.True(value.EvaluatorException.InnerException is
TestSerializableException);
+ Assert.Equal(ExpectedException,
value.EvaluatorException.InnerException.Message);
+ Logger.Log(Level.Info, FailedEvaluatorReceived);
+ }
+
+ public void OnNext(IActiveContext value)
+ {
+ Assert.Equal(ContextId0, value.Id);
+
value.SubmitContext(GetContextStartExceptionContextConfiguration(ContextId1));
+ }
+
+ public void OnNext(ICompletedTask value)
+ {
+ Assert.Equal(TaskId, value.Id);
+ Assert.Equal(ContextId0, value.ActiveContext.Id);
+ Logger.Log(Level.Info, CompletedTaskReceived);
+ value.ActiveContext.Dispose();
+ }
+
+ public void OnError(Exception error)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnCompleted()
+ {
+ throw new NotImplementedException();
+ }
+
+ private static IConfiguration
GetContextStartExceptionContextConfiguration(string contextId)
+ {
+ return ContextConfiguration.ConfigurationModule
+ .Set(ContextConfiguration.Identifier, contextId)
+ .Set(ContextConfiguration.OnContextStart,
GenericType<ContextStartExceptionHandler>.Class)
+ .Build();
+ }
+ }
+
+ private sealed class ContextStartExceptionTask : ITask
+ {
+ [Inject]
+ private ContextStartExceptionTask()
+ {
+ }
+
+ public byte[] Call(byte[] memento)
+ {
+ return null;
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ private sealed class ContextStartExceptionHandler :
IObserver<IContextStart>
+ {
+ [Inject]
+ private ContextStartExceptionHandler()
+ {
+ }
+
+ public void OnNext(IContextStart value)
+ {
+ throw new TestSerializableException(ExpectedException);
+ }
+
+ public void OnError(Exception error)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void OnCompleted()
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/reef/blob/6f482d50/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
----------------------------------------------------------------------
diff --git a/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
b/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
index 4c5996a..c76a0f4 100644
--- a/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
+++ b/lang/cs/Org.Apache.REEF.Tests/Org.Apache.REEF.Tests.csproj
@@ -82,6 +82,7 @@ under the License.
<Compile Include="Functional\Common\Task\ExceptionTask.cs" />
<Compile
Include="Functional\Failure\User\ServiceConstructorExceptionTest.cs" />
<Compile
Include="Functional\Failure\User\ReceiveContextMessageExceptionTest.cs" />
+ <Compile Include="Functional\Failure\User\ContextStartExceptionTest.cs" />
<Compile Include="Functional\Failure\User\TaskCallExceptionTest.cs" />
<Compile
Include="Functional\Bridge\Exceptions\TestNonSerializableException.cs" />
<Compile
Include="Functional\Bridge\Exceptions\TestSerializableException.cs" />