On 23 September 2015 at 15:47, Benjamin Mahler <benjamin.mah...@gmail.com>
wrote:

> +dev
>
> Just so the rest of the dev community understands, are these kinds of event
> based hooks going to be subsumed by a mechanism to stream out cluster
> events? Or will these hooks co-exist alongside cluster events?
>

Could definitely be. All modules have to be (re)built for new Mesos
releases; if they can listen to a SlaveLost event, then we can obsolete the
explicit hooks.

Niklas

>
> On Wed, Sep 23, 2015 at 3:38 PM, <nniel...@apache.org> wrote:
>
> > Added masterSlaveLostHook.
> >
> > This patch adds a new masterSlaveLost hook to enable modules to clean up
> > after lost slaves events (as in networking modules, where we want to
> > avoid leaking IPs).
> >
> > Review: https://reviews.apache.org/r/38575
> >
> >
> > Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
> > Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1d86932c
> > Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1d86932c
> > Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1d86932c
> >
> > Branch: refs/heads/master
> > Commit: 1d86932ce424f3e7b921cc6a436051a45f704dd0
> > Parents: f6706e8
> > Author: Niklas Nielsen <n...@qni.dk>
> > Authored: Wed Sep 23 15:37:21 2015 -0700
> > Committer: Niklas Q. Nielsen <nik...@mesosphere.io>
> > Committed: Wed Sep 23 15:37:24 2015 -0700
> >
> > ----------------------------------------------------------------------
> >  include/mesos/hook.hpp            | 10 +++++++
> >  src/examples/test_hook_module.cpp | 26 +++++++++++++++++
> >  src/hook/manager.cpp              | 12 ++++++++
> >  src/hook/manager.hpp              |  2 ++
> >  src/master/master.cpp             |  5 ++++
> >  src/tests/hook_tests.cpp          | 53
> ++++++++++++++++++++++++++++++++++
> >  6 files changed, 108 insertions(+)
> > ----------------------------------------------------------------------
> >
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/1d86932c/include/mesos/hook.hpp
> > ----------------------------------------------------------------------
> > diff --git a/include/mesos/hook.hpp b/include/mesos/hook.hpp
> > index 2353602..2fe060e 100644
> > --- a/include/mesos/hook.hpp
> > +++ b/include/mesos/hook.hpp
> > @@ -62,6 +62,16 @@ public:
> >      return None();
> >    }
> >
> > +
> > +  // This hook is called when an Agent is removed i.e. deemed lost by
> the
> > +  // master. The hook is invoked after all frameworks have been informed
> > about
> > +  // the loss.
> > +  virtual Try<Nothing> masterSlaveLostHook(const SlaveInfo& slaveInfo)
> > +  {
> > +    return Nothing();
> > +  }
> > +
> > +
> >    // This environment decorator hook is called from within slave when
> >    // launching a new executor. A module implementing the hook creates
> >    // and returns a set of environment variables. These environment
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/1d86932c/src/examples/test_hook_module.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/examples/test_hook_module.cpp
> > b/src/examples/test_hook_module.cpp
> > index 5c4d71a..c09d7dd 100644
> > --- a/src/examples/test_hook_module.cpp
> > +++ b/src/examples/test_hook_module.cpp
> > @@ -108,6 +108,32 @@ public:
> >      return labels;
> >    }
> >
> > +  virtual Try<Nothing> masterSlaveLostHook(const SlaveInfo& slaveInfo)
> > +  {
> > +    LOG(INFO) << "Executing 'masterSlaveLostHook' in slave '"
> > +              << slaveInfo.id() << "'";
> > +
> > +    // TODO(nnielsen): Add argument to signal(), so we can filter
> > messages from
> > +    // the `masterSlaveLostHook` from `slaveRemoveExecutorHook`.
> > +    // NOTE: Will not be a problem **as long as** the test doesn't start
> > any
> > +    // tasks.
> > +    HookProcess hookProcess;
> > +    process::spawn(&hookProcess);
> > +    Future<Nothing> future =
> > +      process::dispatch(hookProcess, &HookProcess::await);
> > +
> > +    process::dispatch(hookProcess, &HookProcess::signal);
> > +
> > +    // Make sure we don't terminate the process before the message
> > self-send has
> > +    // completed.
> > +    future.await();
> > +
> > +    process::terminate(hookProcess);
> > +    process::wait(hookProcess);
> > +
> > +    return Nothing();
> > +  }
> > +
> >    // TODO(nnielsen): Split hook tests into multiple modules to avoid
> >    // interference.
> >    virtual Result<Labels> slaveRunTaskLabelDecorator(
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/1d86932c/src/hook/manager.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/hook/manager.cpp b/src/hook/manager.cpp
> > index 691976e..52d53f0 100644
> > --- a/src/hook/manager.cpp
> > +++ b/src/hook/manager.cpp
> > @@ -133,6 +133,18 @@ Labels HookManager::masterLaunchTaskLabelDecorator(
> >  }
> >
> >
> > +void HookManager::masterSlaveLostHook(const SlaveInfo& slaveInfo)
> > +{
> > +  foreachpair (const string& name, Hook* hook, availableHooks) {
> > +    Try<Nothing> result = hook->masterSlaveLostHook(slaveInfo);
> > +    if (result.isError()) {
> > +      LOG(WARNING) << "Master slave-lost hook failed for module '"
> > +                   << name << "': " << result.error();
> > +    }
> > +  }
> > +}
> > +
> > +
> >  Labels HookManager::slaveRunTaskLabelDecorator(
> >      const TaskInfo& taskInfo,
> >      const ExecutorInfo& executorInfo,
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/1d86932c/src/hook/manager.hpp
> > ----------------------------------------------------------------------
> > diff --git a/src/hook/manager.hpp b/src/hook/manager.hpp
> > index a517c05..d35a762 100644
> > --- a/src/hook/manager.hpp
> > +++ b/src/hook/manager.hpp
> > @@ -45,6 +45,8 @@ public:
> >        const FrameworkInfo& frameworkInfo,
> >        const SlaveInfo& slaveInfo);
> >
> > +  static void masterSlaveLostHook(const SlaveInfo& slaveInfo);
> > +
> >    static Labels slaveRunTaskLabelDecorator(
> >        const TaskInfo& taskInfo,
> >        const ExecutorInfo& executorInfo,
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/1d86932c/src/master/master.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/master/master.cpp b/src/master/master.cpp
> > index 5ca1941..0a40bc3 100644
> > --- a/src/master/master.cpp
> > +++ b/src/master/master.cpp
> > @@ -5998,6 +5998,11 @@ void Master::_removeSlave(
> >      message.mutable_slave_id()->MergeFrom(slaveInfo.id());
> >      framework->send(message);
> >    }
> > +
> > +  // Finally, notify the `SlaveLost` hooks.
> > +  if (HookManager::hooksAvailable()) {
> > +    HookManager::masterSlaveLostHook(slaveInfo);
> > +  }
> >  }
> >
> >
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/1d86932c/src/tests/hook_tests.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/tests/hook_tests.cpp b/src/tests/hook_tests.cpp
> > index f85d917..c9d35fb 100644
> > --- a/src/tests/hook_tests.cpp
> > +++ b/src/tests/hook_tests.cpp
> > @@ -18,6 +18,7 @@
> >
> >  #include <mesos/module.hpp>
> >
> > +#include <process/clock.hpp>
> >  #include <process/future.hpp>
> >  #include <process/gmock.hpp>
> >  #include <process/pid.hpp>
> > @@ -61,6 +62,7 @@ using mesos::internal::slave::Fetcher;
> >  using mesos::internal::slave::MesosContainerizer;
> >  using mesos::internal::slave::Slave;
> >
> > +using process::Clock;
> >  using process::Future;
> >  using process::PID;
> >  using process::Shared;
> > @@ -71,6 +73,7 @@ using std::vector;
> >
> >  using testing::_;
> >  using testing::DoAll;
> > +using testing::Eq;
> >  using testing::Return;
> >  using testing::SaveArg;
> >
> > @@ -212,6 +215,56 @@ TEST_F(HookTest, VerifyMasterLaunchTaskHook)
> >  }
> >
> >
> > +// This test forces a `SlaveLost` event. When this happens, we expect
> the
> > +// `masterSlaveLostHook` to be invoked and await an internal libprocess
> > event
> > +// to trigger in the module code.
> > +TEST_F(HookTest, MasterSlaveLostHookTest)
> > +{
> > +  Future<HookExecuted> hookFuture = FUTURE_PROTOBUF(HookExecuted(), _,
> _);
> > +
> > +  DROP_MESSAGES(Eq(PingSlaveMessage().GetTypeName()), _, _);
> > +
> > +  master::Flags masterFlags = CreateMasterFlags();
> > +
> > +  // Speed up timeout cycles.
> > +  masterFlags.slave_ping_timeout = Seconds(1);
> > +  masterFlags.max_slave_ping_timeouts = 1;
> > +
> > +  Try<PID<Master>> master = StartMaster(masterFlags);
> > +  ASSERT_SOME(master);
> > +
> > +  MockExecutor exec(DEFAULT_EXECUTOR_ID);
> > +
> > +  TestContainerizer containerizer(&exec);
> > +
> > +  Future<SlaveRegisteredMessage> slaveRegisteredMessage =
> > +    FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _);
> > +
> > +  // Start a mock Agent since we aren't testing the slave hooks.
> > +  Try<PID<Slave>> slave = StartSlave(&containerizer);
> > +  ASSERT_SOME(slave);
> > +
> > +  // Make sure Agent is up and running.
> > +  AWAIT_READY(slaveRegisteredMessage);
> > +
> > +  // Forward clock slave timeout.
> > +  Duration totalTimeout =
> > +    masterFlags.slave_ping_timeout *
> masterFlags.max_slave_ping_timeouts;
> > +
> > +  Clock::pause();
> > +  Clock::advance(totalTimeout);
> > +  Clock::settle();
> > +  Clock::resume();
> > +
> > +  // `masterSlaveLostHook()` should be called from within module code.
> > +  AWAIT_READY(hookFuture);
> > +
> > +  // TODO(nnielsen): Verify hook signal type.
> > +
> > +  Shutdown(); // Must shutdown before 'containerizer' gets deallocated.
> > +}
> > +
> > +
> >  // Test that the environment decorator hook adds a new environment
> >  // variable to the executor runtime.
> >  // Test hook adds a new environment variable "FOO" to the executor
> >
> >
>

Reply via email to