I apologize; mix of terminology. Things we call XYZ*Hook*() only returns
Future<Nothing> and can't mutate anything; those are the ones I meant.
The others are all annotated with XYZ*Decorator*() and can change the
object in flight, and yes - I don't think these can be done with event
subscribers, unless we have something like event filters :)

Don't get me wrong; I love the idea of having this be done much more
transparent. It's just not clear what form they will have or how module
writers can interact/use them; that's why I am hesitant about hinting them
coming up in the code.

Niklas

On 23 September 2015 at 17:10, Benjamin Mahler <bmah...@twitter.com.invalid>
wrote:

> My understanding was that it doesn't apply to all hooks because some hooks
> mutate data (e.g. add labels), whereas some hooks are "read-only"
> event-like hooks.
>
> On Wed, Sep 23, 2015 at 4:37 PM, Niklas Nielsen <nik...@mesosphere.io>
> wrote:
>
> > It applies to all hooks; so I don't think a TODO fit well around the
> > mastSlaveLostHook() as a one-off. Do you want it for each hook or in the
> > module docs?
> > As long as the plans around eventing and subscribing to events from
> modules
> > haven't been solidified more, I'd suggest we post-pone adding it as it
> > isn't an alternative (yet).
> >
> > Niklas
> >
> > On 23 September 2015 at 16:29, Benjamin Mahler
> <bmah...@twitter.com.invalid
> > >
> > wrote:
> >
> > > Ok, any plan to add TODOs with this context?
> > >
> > > On Wed, Sep 23, 2015 at 4:11 PM, Niklas Nielsen <nik...@mesosphere.io>
> > > wrote:
> > >
> > > > 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