You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2017/09/01 02:58:13 UTC

[1/3] mesos git commit: Used 'undiscardable' to protect a future in MesosContainerizer.

Repository: mesos
Updated Branches:
  refs/heads/1.2.x 928751aa3 -> 55c26c27f


Used 'undiscardable' to protect a future in MesosContainerizer.

This patch addressed MESOS-7926 by protecting 'termination.future()'
with 'undiscardable'. This prevented the upstream discard event from
being propagated into 'termination.future()' which gets reused for
other calls.

Review: https://reviews.apache.org/r/62005


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2fddf716
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2fddf716
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2fddf716

Branch: refs/heads/1.2.x
Commit: 2fddf7160f28c1a3639670e728fab9c3ce566415
Parents: dfc0f85
Author: Jie Yu <yu...@gmail.com>
Authored: Wed Aug 30 17:28:05 2017 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Thu Aug 31 19:55:14 2017 -0700

----------------------------------------------------------------------
 src/slave/containerizer/mesos/containerizer.cpp | 21 +++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/2fddf716/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index 5c4e625..369c546 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -1922,7 +1922,12 @@ Future<Option<ContainerTermination>> MesosContainerizerProcess::wait(
     return None();
   }
 
-  return containers_.at(containerId)->termination.future()
+  // NOTE: Use 'undiscardable' here to make sure discard from the
+  // caller does not propagate into 'termination.future()' which will
+  // be used in 'destroy()'. We don't want a discard on 'wait()' call
+  // to affect future calls to 'destroy()'. See more details in
+  // MESOS-7926.
+  return undiscardable(containers_.at(containerId)->termination.future())
     .then(Option<ContainerTermination>::some);
 }
 
@@ -2119,7 +2124,12 @@ Future<bool> MesosContainerizerProcess::destroy(
   const Owned<Container>& container = containers_.at(containerId);
 
   if (container->state == DESTROYING) {
-    return container->termination.future()
+    // NOTE: Use 'undiscardable' here to make sure discard from the
+    // caller does not propagate into 'termination.future()' which
+    // will be used in 'wait()'. We don't want a discard on
+    // 'destroy()' call to affect future calls to 'wait()'. See more
+    // details in MESOS-7926.
+    return undiscardable(container->termination.future())
       .then([]() { return true; });
   }
 
@@ -2143,7 +2153,12 @@ Future<bool> MesosContainerizerProcess::destroy(
       return Nothing();
     }));
 
-  return container->termination.future()
+  // NOTE: Use 'undiscardable' here to make sure discard from the
+  // caller does not propagate into 'termination.future()' which will
+  // be used in 'wait()'. We don't want a discard on 'destroy()' call
+  // to affect future calls to 'wait()'. See more details in
+  // MESOS-7926.
+  return undiscardable(container->termination.future())
     .then([]() { return true; });
 }
 


[3/3] mesos git commit: Added MESOS-7926 to 1.2.3 CHANGELOG.

Posted by ji...@apache.org.
Added MESOS-7926 to 1.2.3 CHANGELOG.


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/55c26c27
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/55c26c27
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/55c26c27

Branch: refs/heads/1.2.x
Commit: 55c26c27f3d2785a13dad8182a002a36f5141304
Parents: 2fddf71
Author: Jie Yu <yu...@gmail.com>
Authored: Thu Aug 31 19:57:19 2017 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Thu Aug 31 19:58:09 2017 -0700

----------------------------------------------------------------------
 CHANGELOG | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/55c26c27/CHANGELOG
----------------------------------------------------------------------
diff --git a/CHANGELOG b/CHANGELOG
index e87d7bc..ae28a1e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@ All Issues:
   * [MESOS-7863] - Agent may drop pending kill task status updates.
   * [MESOS-7865] - Agent may process a kill task and still launch the task.
   * [MESOS-7909] - Ordering dependency between 'linux/capabilities' and 'docker/runtime' isolator.
+  * [MESOS-7926] - Abnormal termination of default executor can cause MesosContainerizer::destroy to fail.
 
 
 Release Notes - Mesos - Version 1.2.2


[2/3] mesos git commit: Added an undiscardable() helper that blocks discards from propagating.

Posted by ji...@apache.org.
Added an undiscardable() helper that blocks discards from propagating.

This can be useful in circumstances where you don't want some
asynchronous operation to be canceled.

Review: https://reviews.apache.org/r/61987


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/dfc0f854
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/dfc0f854
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/dfc0f854

Branch: refs/heads/1.2.x
Commit: dfc0f854f5bfeaca246bc589762e37604489bf4a
Parents: 928751a
Author: Benjamin Hindman <be...@gmail.com>
Authored: Tue Aug 29 23:23:36 2017 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Thu Aug 31 19:55:14 2017 -0700

----------------------------------------------------------------------
 3rdparty/libprocess/include/process/future.hpp | 91 +++++++++++++++++++++
 3rdparty/libprocess/src/tests/future_tests.cpp | 41 ++++++++++
 2 files changed, 132 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/dfc0f854/3rdparty/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/future.hpp b/3rdparty/libprocess/include/process/future.hpp
index 819ee5c..ccb78f2 100644
--- a/3rdparty/libprocess/include/process/future.hpp
+++ b/3rdparty/libprocess/include/process/future.hpp
@@ -1610,6 +1610,97 @@ void discardPromises(std::set<Promise<T>*>* promises, const Future<T>& future)
   }
 }
 
+
+// Returns a future that will not propagate a discard through to the
+// future passed in as an argument. This can be very valuable if you
+// want to block some future from getting discarded.
+//
+// Example:
+//
+//   Promise<int> promise;
+//   Future<int> future = undiscardable(promise.future());
+//   future.discard();
+//   assert(!promise.future().hasDiscard());
+//
+// Or another example, when chaining futures:
+//
+//   Future<int> future = undiscardable(
+//       foo()
+//         .then([]() { ...; })
+//         .then([]() { ...; }));
+//
+// This will guarantee that a discard _will not_ propagate to `foo()`
+// or any of the futures returned from the invocations of `.then()`.
+template <typename T>
+Future<T> undiscardable(const Future<T>& future)
+{
+  std::shared_ptr<Promise<T>> promise(new Promise<T>());
+  future.onAny([promise](const Future<T>& future) {
+    promise->associate(future);
+  });
+  return promise->future();
+}
+
+
+// Decorator that for some callable `f` invokes
+// `undiscardable(f(args))` for some `args`. This is used by the
+// overload of `undiscardable()` that takes callables instead of a
+// specialization of `Future`.
+//
+// TODO(benh): Factor out a generic decorator pattern to be used in
+// other circumstances, e.g., to replace `_Deferred`.
+template <typename F>
+struct UndiscardableDecorator
+{
+  template <
+    typename G,
+    typename std::enable_if<
+      std::is_constructible<F, G>::value, int>::type = 0>
+  UndiscardableDecorator(G&& g) : f(std::forward<G>(g)) {}
+
+  template <typename... Args>
+  auto operator()(Args&&... args)
+    -> decltype(std::declval<F&>()(std::forward<Args>(args)...))
+  {
+    using Result =
+      typename std::decay<decltype(f(std::forward<Args>(args)...))>::type;
+
+    static_assert(
+        is_specialization_of<Future, Result>::value,
+        "Expecting Future<T> to be returned from undiscarded(...)");
+
+    return undiscardable(f(std::forward<Args>(args)...));
+  }
+
+  F f;
+};
+
+
+// An overload of `undiscardable()` above that takes and returns a
+// callable. The returned callable has decorated the provided callable
+// `f` such that when the returned callable is invoked it will in turn
+// invoke `undiscardable(f(args))` for some `args`. See
+// `UndiscardableDecorator` above for more details.
+//
+// Example:
+//
+//   Future<int> future = foo()
+//     .then(undiscardable([]() { ...; }));
+//
+// This guarantees that even if `future` is discarded the discard will
+// not propagate into the lambda passed into `.then()`.
+template <
+  typename F,
+  typename std::enable_if<
+    !is_specialization_of<
+      Future,
+      typename std::decay<F>::type>::value, int>::type = 0>
+UndiscardableDecorator<typename std::decay<F>::type> undiscardable(F&& f)
+{
+  return UndiscardableDecorator<
+    typename std::decay<F>::type>(std::forward<F>(f));
+}
+
 }  // namespace process {
 
 #endif // __PROCESS_FUTURE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/dfc0f854/3rdparty/libprocess/src/tests/future_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/future_tests.cpp b/3rdparty/libprocess/src/tests/future_tests.cpp
index 380755f..4285ee9 100644
--- a/3rdparty/libprocess/src/tests/future_tests.cpp
+++ b/3rdparty/libprocess/src/tests/future_tests.cpp
@@ -26,6 +26,7 @@ using process::Clock;
 using process::Failure;
 using process::Future;
 using process::Promise;
+using process::undiscardable;
 
 using std::string;
 
@@ -543,3 +544,43 @@ TEST(FutureTest, ArrowOperator)
   Future<string> s = string("hello");
   EXPECT_EQ(5u, s->size());
 }
+
+
+TEST(FutureTest, UndiscardableFuture)
+{
+  Promise<int> promise;
+
+  Future<int> f = undiscardable(promise.future());
+
+  f.discard();
+
+  EXPECT_TRUE(f.hasDiscard());
+  EXPECT_FALSE(promise.future().hasDiscard());
+
+  promise.set(42);
+
+  AWAIT_ASSERT_EQ(42, f);
+}
+
+
+TEST(FutureTest, UndiscardableLambda)
+{
+  Promise<int> promise;
+
+  Future<int> f = Future<int>(2)
+    .then(undiscardable([&](int multiplier) {
+      return promise.future()
+        .then([=](int i) {
+          return i * multiplier;
+        });
+    }));
+
+  f.discard();
+
+  EXPECT_TRUE(f.hasDiscard());
+  EXPECT_FALSE(promise.future().hasDiscard());
+
+  promise.set(42);
+
+  AWAIT_ASSERT_EQ(84, f);
+}