Guangya file a ticket https://issues.apache.org/jira/browse/MESOS-4924
related to this.

On Sat, Mar 12, 2016 at 10:55 AM, Benjamin Mahler <[email protected]>
wrote:

> +vinod
>
> This breaks the build for me on OS X, it appears this line is the culprit:
>
>     EXTRA_LINK_ARGS = ['-Wl,--as-needed']
>
> This leads to the following:
>
> clang++ -bundle -undefined dynamic_lookup -arch x86_64 -arch i386 -Wl,-F.
> -L/usr/local/opt/subversion/lib -O2 -O2 -Wno-unused-local-typedef
> -std=c++11 -stdlib=libc++ -DGTEST_USE_OWN_TR1_TUPLE=1 -DGTEST_LANG_CXX11
> -Qunused-arguments -I/usr/local/opt/subversion/include/subversion-1
> -I/usr/include/apr-1 -I/usr/include/apr-1.0 -Qunused-arguments
>
> build/temp.macosx-10.11-intel-2.7/src/mesos/executor/mesos_executor_driver_impl.o
> build/temp.macosx-10.11-intel-2.7/src/mesos/executor/module.o
> build/temp.macosx-10.11-intel-2.7/src/mesos/executor/proxy_executor.o
> /Users/bmahler/git/mesos/build/src/.libs/libmesos_no_3rdparty.a
> /Users/bmahler/git/mesos/build/3rdparty/libprocess/.libs/libprocess.a
> /Users/bmahler/git/mesos/build/3rdparty/leveldb-1.4/libleveldb.a
>
> /Users/bmahler/git/mesos/build/3rdparty/zookeeper-3.4.5/src/c/.libs/libzookeeper_mt.a
>
> /Users/bmahler/git/mesos/build/3rdparty/libprocess/3rdparty/glog-0.3.3/.libs/libglog.a
>
> /Users/bmahler/git/mesos/build/3rdparty/libprocess/3rdparty/protobuf-2.5.0/src/.libs/libprotobuf.a
> -o build/lib.macosx-10.11-intel-2.7/mesos/executor/_executor.so
> -Wl,--as-needed -L/usr/local/opt/subversion/lib -levent_openssl -lcrypto
> -lssl -levent_pthreads -levent -lsasl2 -lsvn_delta-1 -lsvn_subr-1 -lapr-1
> -lcurl -lz
> ld: unknown option: --as-needed
> clang: error: linker command failed with exit code 1 (use -v to see
> invocation)
>
> On Fri, Mar 11, 2016 at 1:56 PM, <[email protected]> wrote:
>
> > New python lib with only the executor driver.
> >
> > This patch produces a new python egg, mesos.executor, which contains only
> > the
> > code needed to create a MesosExecutorDriver.  By doing so, the linker can
> > remove
> > unused code in libmesos_no_3rdparty.a, and therefor not include any
> > external
> > dependencies in the resulting _mesos.so.
> >
> > Review: https://reviews.apache.org/r/41049/
> >
> >
> > Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
> > Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c81a52ec
> > Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c81a52ec
> > Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c81a52ec
> >
> > Branch: refs/heads/master
> > Commit: c81a52ec22266e1f2beb61b224c0f0d9be82521f
> > Parents: 482dc14
> > Author: Steve Niemitz <[email protected]>
> > Authored: Fri Mar 11 16:56:13 2016 -0500
> > Committer: Vinod Kone <[email protected]>
> > Committed: Fri Mar 11 16:56:13 2016 -0500
> >
> > ----------------------------------------------------------------------
> >  configure.ac                                    |   7 +-
> >  src/Makefile.am                                 |  33 +-
> >  src/python/executor/setup.py.in                 |  39 +
> >  src/python/executor/src/mesos/__init__.py       |  10 +
> >  .../executor/src/mesos/executor/__init__.py     |  17 +
> >  .../executor/mesos_executor_driver_impl.cpp     | 347 ++++++++
> >  .../executor/mesos_executor_driver_impl.hpp     | 103 +++
> >  .../executor/src/mesos/executor/module.cpp      |  91 +++
> >  .../src/mesos/executor/proxy_executor.cpp       | 273 +++++++
> >  .../src/mesos/executor/proxy_executor.hpp       |  64 ++
> >  src/python/native/ext_modules.py.in             | 151 ----
> >  src/python/native/setup.py.in                   |   9 +-
> >  src/python/native/src/mesos/native/__init__.py  |   7 +-
> >  .../mesos/native/mesos_executor_driver_impl.cpp | 347 --------
> >  .../mesos/native/mesos_executor_driver_impl.hpp | 103 ---
> >  .../native/mesos_scheduler_driver_impl.cpp      | 782
> -------------------
> >  .../native/mesos_scheduler_driver_impl.hpp      | 134 ----
> >  src/python/native/src/mesos/native/module.cpp   | 100 ---
> >  src/python/native/src/mesos/native/module.hpp   | 136 ----
> >  .../native/src/mesos/native/proxy_executor.cpp  | 273 -------
> >  .../native/src/mesos/native/proxy_executor.hpp  |  64 --
> >  .../native/src/mesos/native/proxy_scheduler.cpp | 384 ---------
> >  .../native/src/mesos/native/proxy_scheduler.hpp |  72 --
> >  src/python/native_common/common.hpp             | 136 ++++
> >  src/python/native_common/ext_modules.py.in      | 154 ++++
> >  src/python/scheduler/setup.py.in                |  39 +
> >  src/python/scheduler/src/mesos/__init__.py      |  10 +
> >  .../scheduler/src/mesos/scheduler/__init__.py   |  17 +
> >  .../scheduler/mesos_scheduler_driver_impl.cpp   | 782
> +++++++++++++++++++
> >  .../scheduler/mesos_scheduler_driver_impl.hpp   | 134 ++++
> >  .../scheduler/src/mesos/scheduler/module.cpp    |  91 +++
> >  .../src/mesos/scheduler/proxy_scheduler.cpp     | 384 +++++++++
> >  .../src/mesos/scheduler/proxy_scheduler.hpp     |  72 ++
> >  33 files changed, 2795 insertions(+), 2570 deletions(-)
> > ----------------------------------------------------------------------
> >
> >
> > http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/configure.ac
> > ----------------------------------------------------------------------
> > diff --git a/configure.ac b/configure.ac
> > index a20382e..8e4f035 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -1315,8 +1315,13 @@ There are two possible workarounds for this issue:
> >    AC_CONFIG_FILES([src/python/setup.py])
> >    AC_CONFIG_FILES([src/python/cli/setup.py])
> >    AC_CONFIG_FILES([src/python/interface/setup.py])
> > -  AC_CONFIG_FILES([src/python/native/ext_modules.py])
> > +  AC_CONFIG_FILES([src/python/native_common/ext_modules.py])
> > +  AC_CONFIG_FILES([src/python/executor/setup.py])
> >    AC_CONFIG_FILES([src/python/native/setup.py])
> > +  AC_CONFIG_FILES([src/python/scheduler/setup.py])
> > +
> > +
> >
> AC_CONFIG_LINKS([src/python/executor/ext_modules.py:src/python/native_common/ext_modules.py])
> > +
> >
> AC_CONFIG_LINKS([src/python/scheduler/ext_modules.py:src/python/native_common/ext_modules.py])
> >
> >    # When clang is being used, make sure that the distutils python-
> >    # config cflags extraction does not cause build errors (MESOS-1079).
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/Makefile.am
> > ----------------------------------------------------------------------
> > diff --git a/src/Makefile.am b/src/Makefile.am
> > index f59ae12..8abef3b 100644
> > --- a/src/Makefile.am
> > +++ b/src/Makefile.am
> > @@ -1467,18 +1467,23 @@ PYTHON_SOURCE =
> >                      \
> >    python/interface/src/mesos/interface/__init__.py                     \
> >    python/interface/src/mesos/v1/__init__.py                            \
> >    python/interface/src/mesos/v1/interface/__init__.py                  \
> > +  python/native_common/common.hpp                                      \
> >    python/native/src/mesos/__init__.py                                  \
> >    python/native/src/mesos/native/__init__.py                           \
> > -  python/native/src/mesos/native/mesos_executor_driver_impl.cpp
> >       \
> > -  python/native/src/mesos/native/mesos_executor_driver_impl.hpp
> >       \
> > -  python/native/src/mesos/native/mesos_scheduler_driver_impl.cpp       \
> > -  python/native/src/mesos/native/mesos_scheduler_driver_impl.hpp       \
> > -  python/native/src/mesos/native/module.cpp                            \
> > -  python/native/src/mesos/native/module.hpp                            \
> > -  python/native/src/mesos/native/proxy_executor.cpp                    \
> > -  python/native/src/mesos/native/proxy_executor.hpp                    \
> > -  python/native/src/mesos/native/proxy_scheduler.cpp                   \
> > -  python/native/src/mesos/native/proxy_scheduler.hpp                   \
> > +  python/executor/src/mesos/__init__.py
> >       \
> > +  python/executor/src/mesos/executor/__init__.py                       \
> > +  python/executor/src/mesos/executor/mesos_executor_driver_impl.cpp    \
> > +  python/executor/src/mesos/executor/mesos_executor_driver_impl.hpp    \
> > +  python/executor/src/mesos/executor/module.cpp
> >       \
> > +  python/executor/src/mesos/executor/proxy_executor.cpp
> >       \
> > +  python/executor/src/mesos/executor/proxy_executor.hpp
> >       \
> > +  python/scheduler/src/mesos/__init__.py                               \
> > +  python/scheduler/src/mesos/scheduler/__init__.py                     \
> > +  python/scheduler/src/mesos/scheduler/mesos_scheduler_driver_impl.cpp \
> > +  python/scheduler/src/mesos/scheduler/mesos_scheduler_driver_impl.hpp \
> > +  python/scheduler/src/mesos/scheduler/module.cpp                      \
> > +  python/scheduler/src/mesos/scheduler/proxy_scheduler.cpp             \
> > +  python/scheduler/src/mesos/scheduler/proxy_scheduler.hpp             \
> >    python/src/mesos/__init__.py
> >
> >  EXTRA_DIST += $(PYTHON_SOURCE)
> > @@ -1530,14 +1535,18 @@ $(PYTHON_SOURCE):
> >  MESOS_EGGS =
> >              \
> >    python/dist/mesos-$(PACKAGE_VERSION)$(PYTHON_EGG_PUREPY_POSTFIX).egg
> >              \
> >
> >  python/dist/mesos.cli-$(PACKAGE_VERSION)$(PYTHON_EGG_PUREPY_POSTFIX).egg
> >            \
> > +  python/dist/mesos.executor-$(PACKAGE_VERSION)$(PYTHON_EGG_POSTFIX).egg
> >              \
> >
> >
> python/dist/mesos.interface-$(PACKAGE_VERSION)$(PYTHON_EGG_PUREPY_POSTFIX).egg
> >      \
> > -  python/dist/mesos.native-$(PACKAGE_VERSION)$(PYTHON_EGG_POSTFIX).egg
> > +  python/dist/mesos.native-$(PACKAGE_VERSION)$(PYTHON_EGG_POSTFIX).egg
> >              \
> > +
> python/dist/mesos.scheduler-$(PACKAGE_VERSION)$(PYTHON_EGG_POSTFIX).egg
> >
> >  MESOS_WHLS =
> >              \
> >    python/dist/mesos-$(PACKAGE_VERSION)$(PYTHON_WHL_PUREPY_POSTFIX).whl
> >              \
> >
> >  python/dist/mesos.cli-$(PACKAGE_VERSION)$(PYTHON_WHL_PUREPY_POSTFIX).whl
> >            \
> > +  python/dist/mesos.executor-$(PACKAGE_VERSION)$(PYTHON_WHL_POSTFIX).whl
> >              \
> >
> >
> python/dist/mesos.interface-$(PACKAGE_VERSION)$(PYTHON_WHL_PUREPY_POSTFIX).whl
> >      \
> > -  python/dist/mesos.native-$(PACKAGE_VERSION)$(PYTHON_WHL_POSTFIX).whl
> > +  python/dist/mesos.native-$(PACKAGE_VERSION)$(PYTHON_WHL_POSTFIX).whl
> >              \
> > +
> python/dist/mesos.scheduler-$(PACKAGE_VERSION)$(PYTHON_WHL_POSTFIX).whl
> >
> >  # The python source is in directories of the form: python/interface. The
> > make
> >  # target is of the form: python/dist/mesos.interface-0.20.0-py2.7.egg.
> To
> > build
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/setup.py.in
> > ----------------------------------------------------------------------
> > diff --git a/src/python/executor/setup.py.in b/src/python/executor/
> > setup.py.in
> > new file mode 100644
> > index 0000000..76db97f
> > --- /dev/null
> > +++ b/src/python/executor/setup.py.in
> > @@ -0,0 +1,39 @@
> > +#!/usr/bin/env python
> > +
> > +# 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.
> > +
> > +import ext_modules
> > +
> > +config = {
> > +    'name': 'mesos.executor',
> > +    'version': '@PACKAGE_VERSION@',
> > +    'description': 'Mesos native executor driver implementation',
> > +    'author': 'Apache Mesos',
> > +    'author_email': '[email protected]',
> > +    'url': 'http://pypi.python.org/pypi/mesos.executor',
> > +    'namespace_packages': [ 'mesos' ],
> > +    'packages': [ 'mesos', 'mesos.executor' ],
> > +    'package_dir': { '': 'src' },
> > +    'install_requires': [ 'mesos.interface == @PACKAGE_VERSION@' ],
> > +    'license': 'Apache 2.0',
> > +    'keywords': 'mesos',
> > +    'classifiers': [ ],
> > +    'ext_modules': [ ext_modules.executor_module ]
> > +}
> > +
> > +from setuptools import setup
> > +setup(**config)
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/src/mesos/__init__.py
> > ----------------------------------------------------------------------
> > diff --git a/src/python/executor/src/mesos/__init__.py
> > b/src/python/executor/src/mesos/__init__.py
> > new file mode 100644
> > index 0000000..3fcba01
> > --- /dev/null
> > +++ b/src/python/executor/src/mesos/__init__.py
> > @@ -0,0 +1,10 @@
> > +# See
> > http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
> > +# Because python does not normally allow the contents of a package to be
> > +# retrieved from more than one location, this code snippet ensures that
> > the
> > +# namespace package machinery is operating and that the current package
> is
> > +# registered as a namespace package.
> > +try:
> > +    __import__('pkg_resources').declare_namespace(__name__)
> > +except ImportError:
> > +    from pkgutil import extend_path
> > +    __path__ = extend_path(__path__, __name__)
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/src/mesos/executor/__init__.py
> > ----------------------------------------------------------------------
> > diff --git a/src/python/executor/src/mesos/executor/__init__.py
> > b/src/python/executor/src/mesos/executor/__init__.py
> > new file mode 100644
> > index 0000000..6808019
> > --- /dev/null
> > +++ b/src/python/executor/src/mesos/executor/__init__.py
> > @@ -0,0 +1,17 @@
> > +# 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.
> > +
> > +from ._executor import MesosExecutorDriverImpl as MesosExecutorDriver
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.cpp
> > ----------------------------------------------------------------------
> > diff --git
> > a/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.cpp
> > b/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.cpp
> > new file mode 100644
> > index 0000000..4189411
> > --- /dev/null
> > +++
> b/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.cpp
> > @@ -0,0 +1,347 @@
> > +// 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.
> > +
> > +// Python.h must be included before standard headers.
> > +// See: http://docs.python.org/2/c-api/intro.html#include-files
> > +#include <Python.h>
> > +
> > +#include <string>
> > +
> > +#include "common.hpp"
> > +#include "mesos_executor_driver_impl.hpp"
> > +#include "proxy_executor.hpp"
> > +
> > +using namespace mesos;
> > +using namespace mesos::python;
> > +
> > +using std::cerr;
> > +using std::endl;
> > +using std::string;
> > +using std::vector;
> > +using std::map;
> > +
> > +
> > +namespace mesos { namespace python {
> > +
> > +/**
> > + * Python type object for MesosExecutorDriverImpl.
> > + */
> > +PyTypeObject MesosExecutorDriverImplType = {
> > +  PyObject_HEAD_INIT(NULL)
> > +  0,                                               /* ob_size */
> > +  "_mesos.MesosExecutorDriverImpl",                /* tp_name */
> > +  sizeof(MesosExecutorDriverImpl),                 /* tp_basicsize */
> > +  0,                                               /* tp_itemsize */
> > +  (destructor) MesosExecutorDriverImpl_dealloc,    /* tp_dealloc */
> > +  0,                                               /* tp_print */
> > +  0,                                               /* tp_getattr */
> > +  0,                                               /* tp_setattr */
> > +  0,                                               /* tp_compare */
> > +  0,                                               /* tp_repr */
> > +  0,                                               /* tp_as_number */
> > +  0,                                               /* tp_as_sequence */
> > +  0,                                               /* tp_as_mapping */
> > +  0,                                               /* tp_hash */
> > +  0,                                               /* tp_call */
> > +  0,                                               /* tp_str */
> > +  0,                                               /* tp_getattro */
> > +  0,                                               /* tp_setattro */
> > +  0,                                               /* tp_as_buffer */
> > +  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,         /* tp_flags */
> > +  "Private MesosExecutorDriver implementation",    /* tp_doc */
> > +  (traverseproc) MesosExecutorDriverImpl_traverse, /* tp_traverse */
> > +  (inquiry) MesosExecutorDriverImpl_clear,         /* tp_clear */
> > +  0,                                               /* tp_richcompare */
> > +  0,                                               /* tp_weaklistoffset
> */
> > +  0,                                               /* tp_iter */
> > +  0,                                               /* tp_iternext */
> > +  MesosExecutorDriverImpl_methods,                 /* tp_methods */
> > +  0,                                               /* tp_members */
> > +  0,                                               /* tp_getset */
> > +  0,                                               /* tp_base */
> > +  0,                                               /* tp_dict */
> > +  0,                                               /* tp_descr_get */
> > +  0,                                               /* tp_descr_set */
> > +  0,                                               /* tp_dictoffset */
> > +  (initproc) MesosExecutorDriverImpl_init,         /* tp_init */
> > +  0,                                               /* tp_alloc */
> > +  MesosExecutorDriverImpl_new,                     /* tp_new */
> > +};
> > +
> > +
> > +/**
> > + * List of Python methods in MesosExecutorDriverImpl.
> > + */
> > +PyMethodDef MesosExecutorDriverImpl_methods[] = {
> > +  { "start",
> > +    (PyCFunction) MesosExecutorDriverImpl_start,
> > +    METH_NOARGS,
> > +    "Start the driver to connect to Mesos"
> > +  },
> > +  { "stop",
> > +    (PyCFunction) MesosExecutorDriverImpl_stop,
> > +    METH_NOARGS,
> > +    "Stop the driver, disconnecting from Mesos"
> > +  },
> > +  { "abort",
> > +    (PyCFunction) MesosExecutorDriverImpl_abort,
> > +    METH_NOARGS,
> > +    "Abort the driver, disallowing calls from and to the driver"
> > +  },
> > +  { "join",
> > +    (PyCFunction) MesosExecutorDriverImpl_join,
> > +    METH_NOARGS,
> > +    "Wait for a running driver to disconnect from Mesos"
> > +  },
> > +  { "run",
> > +    (PyCFunction) MesosExecutorDriverImpl_run,
> > +    METH_NOARGS,
> > +    "Start a driver and run it, returning when it disconnects from
> Mesos"
> > +  },
> > +  { "sendStatusUpdate",
> > +    (PyCFunction) MesosExecutorDriverImpl_sendStatusUpdate,
> > +    METH_VARARGS,
> > +    "Send a status update for a task"
> > +  },
> > +  { "sendFrameworkMessage",
> > +    (PyCFunction) MesosExecutorDriverImpl_sendFrameworkMessage,
> > +    METH_VARARGS,
> > +    "Send a FrameworkMessage to a slave"
> > +  },
> > +  { NULL }  /* Sentinel */
> > +};
> > +
> > +
> > +/**
> > + * Create, but don't initialize, a new MesosExecutorDriverImpl
> > + * (called by Python before init method).
> > + */
> > +PyObject* MesosExecutorDriverImpl_new(PyTypeObject *type,
> > +                                       PyObject *args,
> > +                                       PyObject *kwds)
> > +{
> > +  MesosExecutorDriverImpl *self;
> > +  self = (MesosExecutorDriverImpl *) type->tp_alloc(type, 0);
> > +  if (self != NULL) {
> > +    self->driver = NULL;
> > +    self->proxyExecutor = NULL;
> > +    self->pythonExecutor = NULL;
> > +  }
> > +  return (PyObject*) self;
> > +}
> > +
> > +
> > +/**
> > + * Initialize a MesosExecutorDriverImpl with constructor arguments.
> > + */
> > +int MesosExecutorDriverImpl_init(MesosExecutorDriverImpl *self,
> > +                                  PyObject *args,
> > +                                  PyObject *kwds)
> > +{
> > +  PyObject *pythonExecutor = NULL;
> > +
> > +  if (!PyArg_ParseTuple(args, "O", &pythonExecutor)) {
> > +    return -1;
> > +  }
> > +
> > +  if (pythonExecutor != NULL) {
> > +    PyObject* tmp = self->pythonExecutor;
> > +    Py_INCREF(pythonExecutor);
> > +    self->pythonExecutor = pythonExecutor;
> > +    Py_XDECREF(tmp);
> > +  }
> > +
> > +  if (self->driver != NULL) {
> > +    delete self->driver;
> > +    self->driver = NULL;
> > +  }
> > +
> > +  if (self->proxyExecutor != NULL) {
> > +    delete self->proxyExecutor;
> > +    self->proxyExecutor = NULL;
> > +  }
> > +
> > +  self->proxyExecutor = new ProxyExecutor(self);
> > +  self->driver = new MesosExecutorDriver(self->proxyExecutor);
> > +
> > +  return 0;
> > +}
> > +
> > +
> > +/**
> > + * Free a MesosExecutorDriverImpl.
> > + */
> > +void MesosExecutorDriverImpl_dealloc(MesosExecutorDriverImpl* self)
> > +{
> > +  if (self->driver != NULL) {
> > +    // We need to wrap the driver destructor in an "allow threads"
> > +    // macro since the MesosExecutorDriver destructor waits for the
> > +    // ExecutorProcess to terminate and there might be a thread that
> > +    // is trying to acquire the GIL to call through the
> > +    // ProxyExecutor. It will only be after this thread executes that
> > +    // the ExecutorProcess might actually get a terminate.
> > +    Py_BEGIN_ALLOW_THREADS
> > +    delete self->driver;
> > +    Py_END_ALLOW_THREADS
> > +    self->driver = NULL;
> > +  }
> > +
> > +  if (self->proxyExecutor != NULL) {
> > +    delete self->proxyExecutor;
> > +    self->proxyExecutor = NULL;
> > +  }
> > +
> > +  MesosExecutorDriverImpl_clear(self);
> > +  self->ob_type->tp_free((PyObject*) self);
> > +}
> > +
> > +
> > +/**
> > + * Traverse fields of a MesosExecutorDriverImpl on a cyclic GC search.
> > + * See http://docs.python.org/extending/newtypes.html.
> > + */
> > +int MesosExecutorDriverImpl_traverse(MesosExecutorDriverImpl* self,
> > +                                      visitproc visit,
> > +                                      void* arg)
> > +{
> > +  Py_VISIT(self->pythonExecutor);
> > +  return 0;
> > +}
> > +
> > +
> > +/**
> > + * Clear fields of a MesosExecutorDriverImpl that can participate in
> > + * GC cycles. See http://docs.python.org/extending/newtypes.html.
> > + */
> > +int MesosExecutorDriverImpl_clear(MesosExecutorDriverImpl* self)
> > +{
> > +  Py_CLEAR(self->pythonExecutor);
> > +  return 0;
> > +}
> > +
> > +
> > +PyObject* MesosExecutorDriverImpl_start(MesosExecutorDriverImpl* self)
> > +{
> > +  if (self->driver == NULL) {
> > +    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > +    return NULL;
> > +  }
> > +
> > +  Status status = self->driver->start();
> > +  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > +}
> > +
> > +
> > +PyObject* MesosExecutorDriverImpl_stop(MesosExecutorDriverImpl* self)
> > +{
> > +  if (self->driver == NULL) {
> > +    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > +    return NULL;
> > +  }
> > +
> > +  Status status = self->driver->stop();
> > +  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > +}
> > +
> > +
> > +PyObject* MesosExecutorDriverImpl_abort(MesosExecutorDriverImpl* self)
> > +{
> > +  if (self->driver == NULL) {
> > +    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > +    return NULL;
> > +  }
> > +
> > +  Status status = self->driver->abort();
> > +  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > +}
> > +
> > +
> > +PyObject* MesosExecutorDriverImpl_join(MesosExecutorDriverImpl* self)
> > +{
> > +  if (self->driver == NULL) {
> > +    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > +    return NULL;
> > +  }
> > +
> > +  Status status;
> > +  Py_BEGIN_ALLOW_THREADS
> > +  status = self->driver->join();
> > +  Py_END_ALLOW_THREADS
> > +  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > +}
> > +
> > +
> > +PyObject* MesosExecutorDriverImpl_run(MesosExecutorDriverImpl* self)
> > +{
> > +  if (self->driver == NULL) {
> > +    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > +    return NULL;
> > +  }
> > +
> > +  Status status;
> > +  Py_BEGIN_ALLOW_THREADS
> > +  status = self->driver->run();
> > +  Py_END_ALLOW_THREADS
> > +  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > +}
> > +
> > +
> > +PyObject* MesosExecutorDriverImpl_sendStatusUpdate(
> > +    MesosExecutorDriverImpl* self,
> > +    PyObject* args)
> > +{
> > +  if (self->driver == NULL) {
> > +    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > +    return NULL;
> > +  }
> > +
> > +  PyObject* statusObj = NULL;
> > +  TaskStatus taskStatus;
> > +  if (!PyArg_ParseTuple(args, "O", &statusObj)) {
> > +    return NULL;
> > +  }
> > +  if (!readPythonProtobuf(statusObj, &taskStatus)) {
> > +    PyErr_Format(PyExc_Exception,
> > +                 "Could not deserialize Python TaskStatus");
> > +    return NULL;
> > +  }
> > +
> > +  Status status = self->driver->sendStatusUpdate(taskStatus);
> > +  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > +}
> > +
> > +
> > +PyObject* MesosExecutorDriverImpl_sendFrameworkMessage(
> > +    MesosExecutorDriverImpl* self,
> > +    PyObject* args)
> > +{
> > +  if (self->driver == NULL) {
> > +    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > +    return NULL;
> > +  }
> > +
> > +  const char* data;
> > +  int length;
> > +  if (!PyArg_ParseTuple(args, "s#", &data, &length)) {
> > +    return NULL;
> > +  }
> > +
> > +  Status status = self->driver->sendFrameworkMessage(string(data,
> > length));
> > +  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > +}
> > +
> > +} // namespace python {
> > +} // namespace mesos {
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.hpp
> > ----------------------------------------------------------------------
> > diff --git
> > a/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.hpp
> > b/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.hpp
> > new file mode 100644
> > index 0000000..6e672f8
> > --- /dev/null
> > +++
> b/src/python/executor/src/mesos/executor/mesos_executor_driver_impl.hpp
> > @@ -0,0 +1,103 @@
> > +// 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.
> > +
> > +#ifndef MESOS_EXECUTOR_DRIVER_IMPL_HPP
> > +#define MESOS_EXECUTOR_DRIVER_IMPL_HPP
> > +
> > +#include <mesos/executor.hpp>
> > +
> > +
> > +namespace mesos { namespace python {
> > +
> > +class ProxyExecutor;
> > +
> > +/**
> > + * Python object structure for MesosExecutorDriverImpl objects.
> > + */
> > +struct MesosExecutorDriverImpl {
> > +    PyObject_HEAD
> > +    /* Type-specific fields go here. */
> > +    MesosExecutorDriver* driver;
> > +    ProxyExecutor* proxyExecutor;
> > +    PyObject* pythonExecutor;
> > +};
> > +
> > +/**
> > + * Python type object for MesosExecutorDriverImpl.
> > + */
> > +extern PyTypeObject MesosExecutorDriverImplType;
> > +
> > +/**
> > + * List of Python methods in MesosExecutorDriverImpl.
> > + */
> > +extern PyMethodDef MesosExecutorDriverImpl_methods[];
> > +
> > +/**
> > + * Create, but don't initialize, a new MesosExecutorDriverImpl
> > + * (called by Python before init method).
> > + */
> > +PyObject* MesosExecutorDriverImpl_new(PyTypeObject *type,
> > +                                      PyObject *args,
> > +                                      PyObject *kwds);
> > +
> > +/**
> > + * Initialize a MesosExecutorDriverImpl with constructor arguments.
> > + */
> > +int MesosExecutorDriverImpl_init(MesosExecutorDriverImpl *self,
> > +                                 PyObject *args,
> > +                                 PyObject *kwds);
> > +
> > +/**
> > + * Free a MesosExecutorDriverImpl.
> > + */
> > +void MesosExecutorDriverImpl_dealloc(MesosExecutorDriverImpl* self);
> > +
> > +/**
> > + * Traverse fields of a MesosExecutorDriverImpl on a cyclic GC search.
> > + * See http://docs.python.org/extending/newtypes.html.
> > + */
> > +int MesosExecutorDriverImpl_traverse(MesosExecutorDriverImpl* self,
> > +                                     visitproc visit,
> > +                                     void* arg);
> > +/**
> > + * Clear fields of a MesosExecutorDriverImpl that can participate in
> > + * GC cycles. See http://docs.python.org/extending/newtypes.html.
> > + */
> > +int MesosExecutorDriverImpl_clear(MesosExecutorDriverImpl* self);
> > +
> > +// MesosExecutorDriverImpl methods.
> > +PyObject* MesosExecutorDriverImpl_start(MesosExecutorDriverImpl* self);
> > +
> > +PyObject* MesosExecutorDriverImpl_stop(MesosExecutorDriverImpl* self);
> > +
> > +PyObject* MesosExecutorDriverImpl_abort(MesosExecutorDriverImpl* self);
> > +
> > +PyObject* MesosExecutorDriverImpl_join(MesosExecutorDriverImpl* self);
> > +
> > +PyObject* MesosExecutorDriverImpl_run(MesosExecutorDriverImpl* self);
> > +
> > +PyObject* MesosExecutorDriverImpl_sendStatusUpdate(
> > +    MesosExecutorDriverImpl* self,
> > +    PyObject* args);
> > +
> > +PyObject* MesosExecutorDriverImpl_sendFrameworkMessage(
> > +    MesosExecutorDriverImpl* self,
> > +    PyObject* args);
> > +
> > +} // namespace python {
> > +} // namespace mesos {
> > +
> > +#endif /* MESOS_EXECUTOR_DRIVER_IMPL_HPP */
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/src/mesos/executor/module.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/python/executor/src/mesos/executor/module.cpp
> > b/src/python/executor/src/mesos/executor/module.cpp
> > new file mode 100644
> > index 0000000..f8c6382
> > --- /dev/null
> > +++ b/src/python/executor/src/mesos/executor/module.cpp
> > @@ -0,0 +1,91 @@
> > +// 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.
> > +
> > +/**
> > + * This file defines the _mesos.so binary module used by the Mesos
> Python
> > API.
> > + * This module contains private implementations of MesosSchedulerDriver
> > and
> > + * MesosExecutorDriver as Python types that get called from the public
> > module
> > + * called mesos (in <root>/src/python/src/mesos.py). This design was
> > chosen
> > + * so that most of the API (e.g. the Scheduler and Executor interfaces)
> > can
> > + * be written in Python, and only the parts that need to call into C++
> are
> > + * in C++. Note that the mesos module also contains public classes
> called
> > + * MesosSchedulerDriver and MesosExecutorDriver. These call into the
> > private
> > + * _mesos.MesosSchedulerDriverImpl and _mesos.MesosExecutorDriverImpl.
> > + */
> > +
> > +// Python.h must be included before standard headers.
> > +// See: http://docs.python.org/2/c-api/intro.html#include-files
> > +#include <Python.h>
> > +
> > +#include <iostream>
> > +
> > +#include <mesos/executor.hpp>
> > +
> > +#include "common.hpp"
> > +#include "mesos_executor_driver_impl.hpp"
> > +#include "proxy_executor.hpp"
> > +
> > +using namespace mesos;
> > +using namespace mesos::python;
> > +
> > +using std::map;
> > +using std::string;
> > +using std::vector;
> > +
> > +
> > +/**
> > + * The Python module object for mesos_pb2 (which contains the protobuf
> > + * classes generated for Python).
> > + */
> > +PyObject* mesos::python::mesos_pb2 = NULL;
> > +
> > +
> > +namespace {
> > +
> > +/**
> > + * Method list for our Python module.
> > + */
> > +PyMethodDef MODULE_METHODS[] = {
> > +  {NULL, NULL, 0, NULL}        /* Sentinel */
> > +};
> > +
> > +} // namespace {
> > +
> > +
> > +/**
> > + * Entry point called by Python to initialize our module.
> > + */
> > +PyMODINIT_FUNC init_executor()
> > +{
> > +  // Ensure that the interpreter's threading support is enabled.
> > +  PyEval_InitThreads();
> > +
> > +  // Import the mesos_pb2 module (on which we depend for protobuf
> classes)
> > +  mesos_pb2 = PyImport_ImportModule("mesos.interface.mesos_pb2");
> > +  if (mesos_pb2 == NULL)
> > +    return;
> > +
> > +  // Initialize our Python types.
> > +  if (PyType_Ready(&MesosExecutorDriverImplType) < 0)
> > +    return;
> > +
> > +  // Create the _mesos module and add our types to it.
> > +  PyObject* module = Py_InitModule("_executor", MODULE_METHODS);
> > +  Py_INCREF(&MesosExecutorDriverImplType);
> > +  PyModule_AddObject(module,
> > +                     "MesosExecutorDriverImpl",
> > +                     (PyObject*) &MesosExecutorDriverImplType);
> > +}
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/src/mesos/executor/proxy_executor.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/python/executor/src/mesos/executor/proxy_executor.cpp
> > b/src/python/executor/src/mesos/executor/proxy_executor.cpp
> > new file mode 100644
> > index 0000000..da1a49b
> > --- /dev/null
> > +++ b/src/python/executor/src/mesos/executor/proxy_executor.cpp
> > @@ -0,0 +1,273 @@
> > +// 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.
> > +
> > +// Python.h must be included before standard headers.
> > +// See: http://docs.python.org/2/c-api/intro.html#include-files
> > +#include <Python.h>
> > +
> > +#include <iostream>
> > +
> > +#include "common.hpp"
> > +#include "mesos_executor_driver_impl.hpp"
> > +#include "proxy_executor.hpp"
> > +
> > +using namespace mesos;
> > +
> > +using std::cerr;
> > +using std::endl;
> > +using std::map;
> > +using std::string;
> > +using std::vector;
> > +
> > +namespace mesos {
> > +namespace python {
> > +
> > +void ProxyExecutor::registered(ExecutorDriver* driver,
> > +                               const ExecutorInfo& executorInfo,
> > +                               const FrameworkInfo& frameworkInfo,
> > +                               const SlaveInfo& slaveInfo)
> > +{
> > +  InterpreterLock lock;
> > +
> > +  PyObject* executorInfoObj = NULL;
> > +  PyObject* frameworkInfoObj = NULL;
> > +  PyObject* slaveInfoObj = NULL;
> > +  PyObject* res = NULL;
> > +
> > +  executorInfoObj = createPythonProtobuf(executorInfo, "ExecutorInfo");
> > +  frameworkInfoObj = createPythonProtobuf(frameworkInfo,
> "FrameworkInfo");
> > +  slaveInfoObj = createPythonProtobuf(slaveInfo, "SlaveInfo");
> > +
> > +  if (executorInfoObj == NULL ||
> > +      frameworkInfoObj == NULL ||
> > +      slaveInfoObj == NULL) {
> > +    goto cleanup; // createPythonProtobuf will have set an exception.
> > +  }
> > +
> > +  res = PyObject_CallMethod(impl->pythonExecutor,
> > +                            (char*) "registered",
> > +                            (char*) "OOOO",
> > +                            impl,
> > +                            executorInfoObj,
> > +                            frameworkInfoObj,
> > +                            slaveInfoObj);
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor registered" << endl;
> > +    goto cleanup;
> > +  }
> > +
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    driver->abort();
> > +  }
> > +  Py_XDECREF(executorInfoObj);
> > +  Py_XDECREF(frameworkInfoObj);
> > +  Py_XDECREF(slaveInfoObj);
> > +  Py_XDECREF(res);
> > +}
> > +
> > +
> > +void ProxyExecutor::reregistered(ExecutorDriver* driver,
> > +                                 const SlaveInfo& slaveInfo)
> > +{
> > +  InterpreterLock lock;
> > +
> > +  PyObject* slaveInfoObj = NULL;
> > +  PyObject* res = NULL;
> > +
> > +  slaveInfoObj = createPythonProtobuf(slaveInfo, "SlaveInfo");
> > +
> > +  if (slaveInfoObj == NULL) {
> > +    goto cleanup; // createPythonProtobuf will have set an exception.
> > +  }
> > +
> > +  res = PyObject_CallMethod(impl->pythonExecutor,
> > +                            (char*) "reregistered",
> > +                            (char*) "OO",
> > +                            impl,
> > +                            slaveInfoObj);
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor re-registered" << endl;
> > +    goto cleanup;
> > +  }
> > +
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    driver->abort();
> > +  }
> > +  Py_XDECREF(slaveInfoObj);
> > +  Py_XDECREF(res);
> > +}
> > +
> > +
> > +void ProxyExecutor::disconnected(ExecutorDriver* driver)
> > +{
> > +  InterpreterLock lock;
> > +  PyObject* res = PyObject_CallMethod(impl->pythonExecutor,
> > +                            (char*) "disconnected",
> > +                            (char*) "O",
> > +                            impl);
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor's disconnected" << endl;
> > +    goto cleanup;
> > +  }
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    driver->abort();
> > +  }
> > +  Py_XDECREF(res);
> > +}
> > +
> > +
> > +void ProxyExecutor::launchTask(ExecutorDriver* driver,
> > +                               const TaskInfo& task)
> > +{
> > +  InterpreterLock lock;
> > +
> > +  PyObject* taskObj = NULL;
> > +  PyObject* res = NULL;
> > +
> > +  taskObj = createPythonProtobuf(task, "TaskInfo");
> > +  if (taskObj == NULL) {
> > +    goto cleanup; // createPythonProtobuf will have set an exception.
> > +  }
> > +
> > +  res = PyObject_CallMethod(impl->pythonExecutor,
> > +                            (char*) "launchTask",
> > +                            (char*) "OO",
> > +                            impl,
> > +                            taskObj);
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor's launchTask" << endl;
> > +    goto cleanup;
> > +  }
> > +
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    driver->abort();
> > +  }
> > +  Py_XDECREF(taskObj);
> > +  Py_XDECREF(res);
> > +}
> > +
> > +
> > +void ProxyExecutor::killTask(ExecutorDriver* driver,
> > +                             const TaskID& taskId)
> > +{
> > +  InterpreterLock lock;
> > +
> > +  PyObject* taskIdObj = NULL;
> > +  PyObject* res = NULL;
> > +
> > +  taskIdObj = createPythonProtobuf(taskId, "TaskID");
> > +  if (taskIdObj == NULL) {
> > +    goto cleanup; // createPythonProtobuf will have set an exception.
> > +  }
> > +
> > +  res = PyObject_CallMethod(impl->pythonExecutor,
> > +                            (char*) "killTask",
> > +                            (char*) "OO",
> > +                            impl,
> > +                            taskIdObj);
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor's killTask" << endl;
> > +    goto cleanup;
> > +  }
> > +
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    driver->abort();
> > +  }
> > +  Py_XDECREF(taskIdObj);
> > +  Py_XDECREF(res);
> > +}
> > +
> > +
> > +void ProxyExecutor::frameworkMessage(ExecutorDriver* driver,
> > +                                     const string& data)
> > +{
> > +  InterpreterLock lock;
> > +
> > +  PyObject* res = NULL;
> > +
> > +  res = PyObject_CallMethod(impl->pythonExecutor,
> > +                            (char*) "frameworkMessage",
> > +                            (char*) "Os#",
> > +                            impl,
> > +                            data.data(),
> > +                            data.length());
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor's frameworkMessage" << endl;
> > +    goto cleanup;
> > +  }
> > +
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    driver->abort();
> > +  }
> > +  Py_XDECREF(res);
> > +}
> > +
> > +
> > +void ProxyExecutor::shutdown(ExecutorDriver* driver)
> > +{
> > +  InterpreterLock lock;
> > +  PyObject* res = PyObject_CallMethod(impl->pythonExecutor,
> > +                            (char*) "shutdown",
> > +                            (char*) "O",
> > +                            impl);
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor's shutdown" << endl;
> > +    goto cleanup;
> > +  }
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    driver->abort();
> > +  }
> > +  Py_XDECREF(res);
> > +}
> > +
> > +
> > +void ProxyExecutor::error(ExecutorDriver* driver, const string& message)
> > +{
> > +  InterpreterLock lock;
> > +  PyObject* res = PyObject_CallMethod(impl->pythonExecutor,
> > +                                      (char*) "error",
> > +                                      (char*) "Os#",
> > +                                      impl,
> > +                                      message.data(),
> > +                                      message.length());
> > +  if (res == NULL) {
> > +    cerr << "Failed to call executor's error" << endl;
> > +    goto cleanup;
> > +  }
> > +cleanup:
> > +  if (PyErr_Occurred()) {
> > +    PyErr_Print();
> > +    // No need for driver.stop(); it should stop itself.
> > +  }
> > +  Py_XDECREF(res);
> > +}
> > +
> > +} // namespace python {
> > +} // namespace mesos {
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/executor/src/mesos/executor/proxy_executor.hpp
> > ----------------------------------------------------------------------
> > diff --git a/src/python/executor/src/mesos/executor/proxy_executor.hpp
> > b/src/python/executor/src/mesos/executor/proxy_executor.hpp
> > new file mode 100644
> > index 0000000..23d64fd
> > --- /dev/null
> > +++ b/src/python/executor/src/mesos/executor/proxy_executor.hpp
> > @@ -0,0 +1,64 @@
> > +// 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.
> > +
> > +#ifndef PROXY_EXECUTOR_HPP
> > +#define PROXY_EXECUTOR_HPP
> > +
> > +// Python.h must be included before standard headers.
> > +// See: http://docs.python.org/2/c-api/intro.html#include-files
> > +#include <Python.h>
> > +
> > +#include <string>
> > +#include <vector>
> > +
> > +#include <mesos/executor.hpp>
> > +
> > +namespace mesos {
> > +namespace python {
> > +
> > +struct MesosExecutorDriverImpl;
> > +
> > +/**
> > + * Proxy Executor implementation that will call into Python.
> > + */
> > +class ProxyExecutor : public Executor
> > +{
> > +public:
> > +  explicit ProxyExecutor(MesosExecutorDriverImpl *_impl) : impl(_impl)
> {}
> > +
> > +  virtual ~ProxyExecutor() {}
> > +
> > +  virtual void registered(ExecutorDriver* driver,
> > +                          const ExecutorInfo& executorInfo,
> > +                          const FrameworkInfo& frameworkInfo,
> > +                          const SlaveInfo& slaveInfo);
> > +  virtual void reregistered(ExecutorDriver* driver, const SlaveInfo&
> > slaveInfo);
> > +  virtual void disconnected(ExecutorDriver* driver);
> > +  virtual void launchTask(ExecutorDriver* driver, const TaskInfo& task);
> > +  virtual void killTask(ExecutorDriver* driver, const TaskID& taskId);
> > +  virtual void frameworkMessage(ExecutorDriver* driver,
> > +                                const std::string& data);
> > +  virtual void shutdown(ExecutorDriver* driver);
> > +  virtual void error(ExecutorDriver* driver, const std::string&
> message);
> > +
> > +private:
> > +  MesosExecutorDriverImpl *impl;
> > +};
> > +
> > +} // namespace python {
> > +} // namespace mesos {
> > +
> > +#endif // PROXY_EXECUTOR_HPP
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/native/ext_modules.py.in
> > ----------------------------------------------------------------------
> > diff --git a/src/python/native/ext_modules.py.in b/src/python/native/
> > ext_modules.py.in
> > deleted file mode 100644
> > index eb93864..0000000
> > --- a/src/python/native/ext_modules.py.in
> > +++ /dev/null
> > @@ -1,151 +0,0 @@
> > -# 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.
> > -
> > -import errno
> > -import glob
> > -import os
> > -import shutil
> > -
> > -from setuptools import Extension
> > -
> > -abs_top_srcdir = '@abs_top_srcdir@'
> > -abs_top_builddir = '@abs_top_builddir@'
> > -
> > -src_python_native = os.path.join(
> > -    'src', 'python', 'native', 'src', 'mesos', 'native')
> > -
> > -leveldb = os.path.join('3rdparty', 'leveldb-1.4')
> > -zookeeper = os.path.join('3rdparty', 'zookeeper-3.4.5', 'src', 'c')
> > -libprocess = os.path.join('3rdparty', 'libprocess')
> > -
> > -# Even though a statically compiled libprocess should include glog,
> > -# libev, gperftools, and protobuf before installation this isn't the
> > -# case, so while a libtool managed build will correctly pull in these
> > -# libraries when building the final result, we need to explicitly
> > -# include them here (or more precisely, down where we actually include
> > -# libev.a and libprofiler.a).
> > -glog = os.path.join(libprocess, '3rdparty', 'glog-0.3.3')
> > -gperftools = os.path.join(libprocess, '3rdparty', 'gperftools-2.0')
> > -protobuf = os.path.join(libprocess, '3rdparty', 'protobuf-2.5.0')
> > -
> > -# Build the list of source files. Note that each source must be
> > -# relative to our current directory (where this script lives).
> > -SOURCES = [
> > -    os.path.join('src', 'mesos', 'native', file)
> > -        for file in os.listdir(os.path.join(abs_top_srcdir,
> > src_python_native))
> > -            if file.endswith('.cpp')
> > -]
> > -
> > -INCLUDE_DIRS = [
> > -    os.path.join(abs_top_srcdir, 'include'),
> > -    os.path.join(abs_top_builddir, 'include'),
> > -    # Needed for the *.pb.h protobuf includes.
> > -    os.path.join(abs_top_builddir, 'include', 'mesos'),
> > -    os.path.join(abs_top_builddir, 'src'),
> > -    os.path.join(abs_top_builddir, src_python_native),
> > -    os.path.join(abs_top_builddir, protobuf, 'src'),
> > -]
> > -
> > -LIBRARY_DIRS = []
> > -
> > -EXTRA_OBJECTS = [
> > -    os.path.join(abs_top_builddir, 'src', '.libs',
> > 'libmesos_no_3rdparty.a'),
> > -    os.path.join(abs_top_builddir, libprocess, '.libs', 'libprocess.a')
> > -]
> > -
> > -# For leveldb, we need to check for the presence of libleveldb.a, since
> > -# it is possible to disable leveldb inside mesos.
> > -libglog = os.path.join(abs_top_builddir, glog, '.libs', 'libglog.a')
> > -libleveldb = os.path.join(abs_top_builddir, leveldb, 'libleveldb.a')
> > -libzookeeper = os.path.join(
> > -    abs_top_builddir, zookeeper, '.libs', 'libzookeeper_mt.a')
> > -libprotobuf = os.path.join(
> > -    abs_top_builddir, protobuf, 'src', '.libs', 'libprotobuf.a')
> > -
> > -if os.path.exists(libleveldb):
> > -    EXTRA_OBJECTS.append(libleveldb)
> > -else:
> > -    EXTRA_OBJECTS.append('-lleveldb')
> > -
> > -if os.path.exists(libzookeeper):
> > -    EXTRA_OBJECTS.append(libzookeeper)
> > -else:
> > -    EXTRA_OBJECTS.append('-lzookeeper_mt')
> > -
> > -if os.path.exists(libglog):
> > -    EXTRA_OBJECTS.append(libglog)
> > -else:
> > -    EXTRA_OBJECTS.append('-lglog')
> > -
> > -if os.path.exists(libprotobuf):
> > -  EXTRA_OBJECTS.append(libprotobuf)
> > -else:
> > -  EXTRA_OBJECTS.append('-lprotobuf')
> > -
> > -
> > -# libev is a special case because it needs to be enabled only when
> > -# libevent *is not* enabled through the top level ./configure.
> > -#
> > -# TODO(hartem): this entire block MUST be removed once libev is
> deprecated
> > -# in favor of libevent.
> > -if '@ENABLE_LIBEVENT_TRUE@' == '#':
> > -    libev = os.path.join(libprocess, '3rdparty', 'libev-4.15')
> > -    libev = os.path.join(abs_top_builddir, libev, '.libs', 'libev.a')
> > -
> > -    if os.path.exists(libev):
> > -        EXTRA_OBJECTS.append(libev)
> > -    else:
> > -        EXTRA_OBJECTS.append('-lev')
> > -
> > -
> > -# For gperftools, we need to check for the presence of libprofiler.a,
> > since
> > -# it is possible to disable perftools inside libprocess.
> > -libprofiler = os.path.join(
> > -    abs_top_builddir, gperftools, '.libs', 'libprofiler.a')
> > -
> > -if os.path.exists(libprofiler):
> > -    EXTRA_OBJECTS.append(libprofiler)
> > -
> > -EXTRA_LINK_ARGS = []
> > -
> > -# Add any flags from LDFLAGS.
> > -if 'LDFLAGS' in os.environ:
> > -    for flag in os.environ['LDFLAGS'].split():
> > -        EXTRA_LINK_ARGS.append(flag)
> > -
> > -# Add any libraries from LIBS.
> > -if 'LIBS' in os.environ:
> > -    for library in os.environ['LIBS'].split():
> > -        EXTRA_LINK_ARGS.append(library)
> > -
> > -DEPENDS = [
> > -    os.path.join(abs_top_srcdir, 'src', 'python', source)
> > -        for source in SOURCES
> > -]
> > -
> > -# Note that we add EXTRA_OBJECTS to our dependency list to make sure
> > -# that we rebuild this module when one of them changes (e.g.,
> > -# libprocess).
> > -mesos_module = \
> > -    Extension('mesos.native._mesos',
> > -              sources = SOURCES,
> > -              include_dirs = INCLUDE_DIRS,
> > -              library_dirs = LIBRARY_DIRS,
> > -              extra_objects = EXTRA_OBJECTS,
> > -              extra_link_args = EXTRA_LINK_ARGS,
> > -              depends = EXTRA_OBJECTS,
> > -              language = 'c++',
> > -              )
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/native/setup.py.in
> > ----------------------------------------------------------------------
> > diff --git a/src/python/native/setup.py.in b/src/python/native/
> setup.py.in
> > index 49ed612..10a5002 100644
> > --- a/src/python/native/setup.py.in
> > +++ b/src/python/native/setup.py.in
> > @@ -16,8 +16,6 @@
> >  # See the License for the specific language governing permissions and
> >  # limitations under the License.
> >
> > -import ext_modules
> > -
> >  config = {
> >      'name': 'mesos.native',
> >      'version': '@PACKAGE_VERSION@',
> > @@ -28,13 +26,12 @@ config = {
> >      'namespace_packages': [ 'mesos' ],
> >      'packages': [ 'mesos', 'mesos.native' ],
> >      'package_dir': { '': 'src' },
> > -    'install_requires': [ 'mesos.interface == @PACKAGE_VERSION@' ],
> > +    'install_requires': [ 'mesos.executor == @PACKAGE_VERSION@',
> > +                          'mesos.scheduler == @PACKAGE_VERSION@'],
> >      'license': 'Apache 2.0',
> >      'keywords': 'mesos',
> > -    'classifiers': [ ],
> > -    'ext_modules': [ ext_modules.mesos_module ]
> > +    'classifiers': [ ]
> >  }
> >
> >  from setuptools import setup
> > -
> >  setup(**config)
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/native/src/mesos/native/__init__.py
> > ----------------------------------------------------------------------
> > diff --git a/src/python/native/src/mesos/native/__init__.py
> > b/src/python/native/src/mesos/native/__init__.py
> > index 226f943..b581537 100644
> > --- a/src/python/native/src/mesos/native/__init__.py
> > +++ b/src/python/native/src/mesos/native/__init__.py
> > @@ -14,8 +14,5 @@
> >  # See the License for the specific language governing permissions and
> >  # limitations under the License.
> >
> > -from ._mesos import MesosExecutorDriverImpl
> > -from ._mesos import MesosSchedulerDriverImpl
> > -
> > -MesosExecutorDriver = MesosExecutorDriverImpl
> > -MesosSchedulerDriver = MesosSchedulerDriverImpl
> > +from mesos.executor import MesosExecutorDriver
> > +from mesos.scheduler import MesosSchedulerDriver
> > \ No newline at end of file
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/native/src/mesos/native/mesos_executor_driver_impl.cpp
> > ----------------------------------------------------------------------
> > diff --git
> > a/src/python/native/src/mesos/native/mesos_executor_driver_impl.cpp
> > b/src/python/native/src/mesos/native/mesos_executor_driver_impl.cpp
> > deleted file mode 100644
> > index 7838a07..0000000
> > --- a/src/python/native/src/mesos/native/mesos_executor_driver_impl.cpp
> > +++ /dev/null
> > @@ -1,347 +0,0 @@
> > -// 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.
> > -
> > -// Python.h must be included before standard headers.
> > -// See: http://docs.python.org/2/c-api/intro.html#include-files
> > -#include <Python.h>
> > -
> > -#include <string>
> > -
> > -#include "mesos_executor_driver_impl.hpp"
> > -#include "module.hpp"
> > -#include "proxy_executor.hpp"
> > -
> > -using namespace mesos;
> > -using namespace mesos::python;
> > -
> > -using std::cerr;
> > -using std::endl;
> > -using std::string;
> > -using std::vector;
> > -using std::map;
> > -
> > -
> > -namespace mesos { namespace python {
> > -
> > -/**
> > - * Python type object for MesosExecutorDriverImpl.
> > - */
> > -PyTypeObject MesosExecutorDriverImplType = {
> > -  PyObject_HEAD_INIT(NULL)
> > -  0,                                               /* ob_size */
> > -  "_mesos.MesosExecutorDriverImpl",                /* tp_name */
> > -  sizeof(MesosExecutorDriverImpl),                 /* tp_basicsize */
> > -  0,                                               /* tp_itemsize */
> > -  (destructor) MesosExecutorDriverImpl_dealloc,    /* tp_dealloc */
> > -  0,                                               /* tp_print */
> > -  0,                                               /* tp_getattr */
> > -  0,                                               /* tp_setattr */
> > -  0,                                               /* tp_compare */
> > -  0,                                               /* tp_repr */
> > -  0,                                               /* tp_as_number */
> > -  0,                                               /* tp_as_sequence */
> > -  0,                                               /* tp_as_mapping */
> > -  0,                                               /* tp_hash */
> > -  0,                                               /* tp_call */
> > -  0,                                               /* tp_str */
> > -  0,                                               /* tp_getattro */
> > -  0,                                               /* tp_setattro */
> > -  0,                                               /* tp_as_buffer */
> > -  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,         /* tp_flags */
> > -  "Private MesosExecutorDriver implementation",    /* tp_doc */
> > -  (traverseproc) MesosExecutorDriverImpl_traverse, /* tp_traverse */
> > -  (inquiry) MesosExecutorDriverImpl_clear,         /* tp_clear */
> > -  0,                                               /* tp_richcompare */
> > -  0,                                               /* tp_weaklistoffset
> */
> > -  0,                                               /* tp_iter */
> > -  0,                                               /* tp_iternext */
> > -  MesosExecutorDriverImpl_methods,                 /* tp_methods */
> > -  0,                                               /* tp_members */
> > -  0,                                               /* tp_getset */
> > -  0,                                               /* tp_base */
> > -  0,                                               /* tp_dict */
> > -  0,                                               /* tp_descr_get */
> > -  0,                                               /* tp_descr_set */
> > -  0,                                               /* tp_dictoffset */
> > -  (initproc) MesosExecutorDriverImpl_init,         /* tp_init */
> > -  0,                                               /* tp_alloc */
> > -  MesosExecutorDriverImpl_new,                     /* tp_new */
> > -};
> > -
> > -
> > -/**
> > - * List of Python methods in MesosExecutorDriverImpl.
> > - */
> > -PyMethodDef MesosExecutorDriverImpl_methods[] = {
> > -  { "start",
> > -    (PyCFunction) MesosExecutorDriverImpl_start,
> > -    METH_NOARGS,
> > -    "Start the driver to connect to Mesos"
> > -  },
> > -  { "stop",
> > -    (PyCFunction) MesosExecutorDriverImpl_stop,
> > -    METH_NOARGS,
> > -    "Stop the driver, disconnecting from Mesos"
> > -  },
> > -  { "abort",
> > -    (PyCFunction) MesosExecutorDriverImpl_abort,
> > -    METH_NOARGS,
> > -    "Abort the driver, disallowing calls from and to the driver"
> > -  },
> > -  { "join",
> > -    (PyCFunction) MesosExecutorDriverImpl_join,
> > -    METH_NOARGS,
> > -    "Wait for a running driver to disconnect from Mesos"
> > -  },
> > -  { "run",
> > -    (PyCFunction) MesosExecutorDriverImpl_run,
> > -    METH_NOARGS,
> > -    "Start a driver and run it, returning when it disconnects from
> Mesos"
> > -  },
> > -  { "sendStatusUpdate",
> > -    (PyCFunction) MesosExecutorDriverImpl_sendStatusUpdate,
> > -    METH_VARARGS,
> > -    "Send a status update for a task"
> > -  },
> > -  { "sendFrameworkMessage",
> > -    (PyCFunction) MesosExecutorDriverImpl_sendFrameworkMessage,
> > -    METH_VARARGS,
> > -    "Send a FrameworkMessage to a slave"
> > -  },
> > -  { NULL }  /* Sentinel */
> > -};
> > -
> > -
> > -/**
> > - * Create, but don't initialize, a new MesosExecutorDriverImpl
> > - * (called by Python before init method).
> > - */
> > -PyObject* MesosExecutorDriverImpl_new(PyTypeObject *type,
> > -                                       PyObject *args,
> > -                                       PyObject *kwds)
> > -{
> > -  MesosExecutorDriverImpl *self;
> > -  self = (MesosExecutorDriverImpl *) type->tp_alloc(type, 0);
> > -  if (self != NULL) {
> > -    self->driver = NULL;
> > -    self->proxyExecutor = NULL;
> > -    self->pythonExecutor = NULL;
> > -  }
> > -  return (PyObject*) self;
> > -}
> > -
> > -
> > -/**
> > - * Initialize a MesosExecutorDriverImpl with constructor arguments.
> > - */
> > -int MesosExecutorDriverImpl_init(MesosExecutorDriverImpl *self,
> > -                                  PyObject *args,
> > -                                  PyObject *kwds)
> > -{
> > -  PyObject *pythonExecutor = NULL;
> > -
> > -  if (!PyArg_ParseTuple(args, "O", &pythonExecutor)) {
> > -    return -1;
> > -  }
> > -
> > -  if (pythonExecutor != NULL) {
> > -    PyObject* tmp = self->pythonExecutor;
> > -    Py_INCREF(pythonExecutor);
> > -    self->pythonExecutor = pythonExecutor;
> > -    Py_XDECREF(tmp);
> > -  }
> > -
> > -  if (self->driver != NULL) {
> > -    delete self->driver;
> > -    self->driver = NULL;
> > -  }
> > -
> > -  if (self->proxyExecutor != NULL) {
> > -    delete self->proxyExecutor;
> > -    self->proxyExecutor = NULL;
> > -  }
> > -
> > -  self->proxyExecutor = new ProxyExecutor(self);
> > -  self->driver = new MesosExecutorDriver(self->proxyExecutor);
> > -
> > -  return 0;
> > -}
> > -
> > -
> > -/**
> > - * Free a MesosExecutorDriverImpl.
> > - */
> > -void MesosExecutorDriverImpl_dealloc(MesosExecutorDriverImpl* self)
> > -{
> > -  if (self->driver != NULL) {
> > -    // We need to wrap the driver destructor in an "allow threads"
> > -    // macro since the MesosExecutorDriver destructor waits for the
> > -    // ExecutorProcess to terminate and there might be a thread that
> > -    // is trying to acquire the GIL to call through the
> > -    // ProxyExecutor. It will only be after this thread executes that
> > -    // the ExecutorProcess might actually get a terminate.
> > -    Py_BEGIN_ALLOW_THREADS
> > -    delete self->driver;
> > -    Py_END_ALLOW_THREADS
> > -    self->driver = NULL;
> > -  }
> > -
> > -  if (self->proxyExecutor != NULL) {
> > -    delete self->proxyExecutor;
> > -    self->proxyExecutor = NULL;
> > -  }
> > -
> > -  MesosExecutorDriverImpl_clear(self);
> > -  self->ob_type->tp_free((PyObject*) self);
> > -}
> > -
> > -
> > -/**
> > - * Traverse fields of a MesosExecutorDriverImpl on a cyclic GC search.
> > - * See http://docs.python.org/extending/newtypes.html.
> > - */
> > -int MesosExecutorDriverImpl_traverse(MesosExecutorDriverImpl* self,
> > -                                      visitproc visit,
> > -                                      void* arg)
> > -{
> > -  Py_VISIT(self->pythonExecutor);
> > -  return 0;
> > -}
> > -
> > -
> > -/**
> > - * Clear fields of a MesosExecutorDriverImpl that can participate in
> > - * GC cycles. See http://docs.python.org/extending/newtypes.html.
> > - */
> > -int MesosExecutorDriverImpl_clear(MesosExecutorDriverImpl* self)
> > -{
> > -  Py_CLEAR(self->pythonExecutor);
> > -  return 0;
> > -}
> > -
> > -
> > -PyObject* MesosExecutorDriverImpl_start(MesosExecutorDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->start();
> > -  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > -}
> > -
> > -
> > -PyObject* MesosExecutorDriverImpl_stop(MesosExecutorDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->stop();
> > -  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > -}
> > -
> > -
> > -PyObject* MesosExecutorDriverImpl_abort(MesosExecutorDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->abort();
> > -  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > -}
> > -
> > -
> > -PyObject* MesosExecutorDriverImpl_join(MesosExecutorDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status;
> > -  Py_BEGIN_ALLOW_THREADS
> > -  status = self->driver->join();
> > -  Py_END_ALLOW_THREADS
> > -  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > -}
> > -
> > -
> > -PyObject* MesosExecutorDriverImpl_run(MesosExecutorDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status;
> > -  Py_BEGIN_ALLOW_THREADS
> > -  status = self->driver->run();
> > -  Py_END_ALLOW_THREADS
> > -  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > -}
> > -
> > -
> > -PyObject* MesosExecutorDriverImpl_sendStatusUpdate(
> > -    MesosExecutorDriverImpl* self,
> > -    PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* statusObj = NULL;
> > -  TaskStatus taskStatus;
> > -  if (!PyArg_ParseTuple(args, "O", &statusObj)) {
> > -    return NULL;
> > -  }
> > -  if (!readPythonProtobuf(statusObj, &taskStatus)) {
> > -    PyErr_Format(PyExc_Exception,
> > -                 "Could not deserialize Python TaskStatus");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->sendStatusUpdate(taskStatus);
> > -  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > -}
> > -
> > -
> > -PyObject* MesosExecutorDriverImpl_sendFrameworkMessage(
> > -    MesosExecutorDriverImpl* self,
> > -    PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosExecutorDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  const char* data;
> > -  int length;
> > -  if (!PyArg_ParseTuple(args, "s#", &data, &length)) {
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->sendFrameworkMessage(string(data,
> > length));
> > -  return PyInt_FromLong(status); // Sets an exception if creating the
> int
> > fails.
> > -}
> > -
> > -} // namespace python {
> > -} // namespace mesos {
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/native/src/mesos/native/mesos_executor_driver_impl.hpp
> > ----------------------------------------------------------------------
> > diff --git
> > a/src/python/native/src/mesos/native/mesos_executor_driver_impl.hpp
> > b/src/python/native/src/mesos/native/mesos_executor_driver_impl.hpp
> > deleted file mode 100644
> > index 6e672f8..0000000
> > --- a/src/python/native/src/mesos/native/mesos_executor_driver_impl.hpp
> > +++ /dev/null
> > @@ -1,103 +0,0 @@
> > -// 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.
> > -
> > -#ifndef MESOS_EXECUTOR_DRIVER_IMPL_HPP
> > -#define MESOS_EXECUTOR_DRIVER_IMPL_HPP
> > -
> > -#include <mesos/executor.hpp>
> > -
> > -
> > -namespace mesos { namespace python {
> > -
> > -class ProxyExecutor;
> > -
> > -/**
> > - * Python object structure for MesosExecutorDriverImpl objects.
> > - */
> > -struct MesosExecutorDriverImpl {
> > -    PyObject_HEAD
> > -    /* Type-specific fields go here. */
> > -    MesosExecutorDriver* driver;
> > -    ProxyExecutor* proxyExecutor;
> > -    PyObject* pythonExecutor;
> > -};
> > -
> > -/**
> > - * Python type object for MesosExecutorDriverImpl.
> > - */
> > -extern PyTypeObject MesosExecutorDriverImplType;
> > -
> > -/**
> > - * List of Python methods in MesosExecutorDriverImpl.
> > - */
> > -extern PyMethodDef MesosExecutorDriverImpl_methods[];
> > -
> > -/**
> > - * Create, but don't initialize, a new MesosExecutorDriverImpl
> > - * (called by Python before init method).
> > - */
> > -PyObject* MesosExecutorDriverImpl_new(PyTypeObject *type,
> > -                                      PyObject *args,
> > -                                      PyObject *kwds);
> > -
> > -/**
> > - * Initialize a MesosExecutorDriverImpl with constructor arguments.
> > - */
> > -int MesosExecutorDriverImpl_init(MesosExecutorDriverImpl *self,
> > -                                 PyObject *args,
> > -                                 PyObject *kwds);
> > -
> > -/**
> > - * Free a MesosExecutorDriverImpl.
> > - */
> > -void MesosExecutorDriverImpl_dealloc(MesosExecutorDriverImpl* self);
> > -
> > -/**
> > - * Traverse fields of a MesosExecutorDriverImpl on a cyclic GC search.
> > - * See http://docs.python.org/extending/newtypes.html.
> > - */
> > -int MesosExecutorDriverImpl_traverse(MesosExecutorDriverImpl* self,
> > -                                     visitproc visit,
> > -                                     void* arg);
> > -/**
> > - * Clear fields of a MesosExecutorDriverImpl that can participate in
> > - * GC cycles. See http://docs.python.org/extending/newtypes.html.
> > - */
> > -int MesosExecutorDriverImpl_clear(MesosExecutorDriverImpl* self);
> > -
> > -// MesosExecutorDriverImpl methods.
> > -PyObject* MesosExecutorDriverImpl_start(MesosExecutorDriverImpl* self);
> > -
> > -PyObject* MesosExecutorDriverImpl_stop(MesosExecutorDriverImpl* self);
> > -
> > -PyObject* MesosExecutorDriverImpl_abort(MesosExecutorDriverImpl* self);
> > -
> > -PyObject* MesosExecutorDriverImpl_join(MesosExecutorDriverImpl* self);
> > -
> > -PyObject* MesosExecutorDriverImpl_run(MesosExecutorDriverImpl* self);
> > -
> > -PyObject* MesosExecutorDriverImpl_sendStatusUpdate(
> > -    MesosExecutorDriverImpl* self,
> > -    PyObject* args);
> > -
> > -PyObject* MesosExecutorDriverImpl_sendFrameworkMessage(
> > -    MesosExecutorDriverImpl* self,
> > -    PyObject* args);
> > -
> > -} // namespace python {
> > -} // namespace mesos {
> > -
> > -#endif /* MESOS_EXECUTOR_DRIVER_IMPL_HPP */
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/c81a52ec/src/python/native/src/mesos/native/mesos_scheduler_driver_impl.cpp
> > ----------------------------------------------------------------------
> > diff --git
> > a/src/python/native/src/mesos/native/mesos_scheduler_driver_impl.cpp
> > b/src/python/native/src/mesos/native/mesos_scheduler_driver_impl.cpp
> > deleted file mode 100644
> > index f8be49b..0000000
> > --- a/src/python/native/src/mesos/native/mesos_scheduler_driver_impl.cpp
> > +++ /dev/null
> > @@ -1,782 +0,0 @@
> > -// 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.
> > -
> > -// Python.h must be included before standard headers.
> > -// See: http://docs.python.org/2/c-api/intro.html#include-files
> > -#include <Python.h>
> > -
> > -#include <string>
> > -
> > -#include "mesos_scheduler_driver_impl.hpp"
> > -#include "module.hpp"
> > -#include "proxy_scheduler.hpp"
> > -
> > -using namespace mesos;
> > -using namespace mesos::python;
> > -
> > -using std::cerr;
> > -using std::endl;
> > -using std::string;
> > -using std::vector;
> > -using std::map;
> > -
> > -namespace mesos {
> > -namespace python {
> > -
> > -/**
> > - * Python type object for MesosSchedulerDriverImpl.
> > - */
> > -PyTypeObject MesosSchedulerDriverImplType = {
> > -  PyObject_HEAD_INIT(NULL)
> > -  0,                                                /* ob_size */
> > -  "_mesos.MesosSchedulerDriverImpl",                /* tp_name */
> > -  sizeof(MesosSchedulerDriverImpl),                 /* tp_basicsize */
> > -  0,                                                /* tp_itemsize */
> > -  (destructor) MesosSchedulerDriverImpl_dealloc,    /* tp_dealloc */
> > -  0,                                                /* tp_print */
> > -  0,                                                /* tp_getattr */
> > -  0,                                                /* tp_setattr */
> > -  0,                                                /* tp_compare */
> > -  0,                                                /* tp_repr */
> > -  0,                                                /* tp_as_number */
> > -  0,                                                /* tp_as_sequence */
> > -  0,                                                /* tp_as_mapping */
> > -  0,                                                /* tp_hash */
> > -  0,                                                /* tp_call */
> > -  0,                                                /* tp_str */
> > -  0,                                                /* tp_getattro */
> > -  0,                                                /* tp_setattro */
> > -  0,                                                /* tp_as_buffer */
> > -  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,          /* tp_flags */
> > -  "Private MesosSchedulerDriver implementation",    /* tp_doc */
> > -  (traverseproc) MesosSchedulerDriverImpl_traverse, /* tp_traverse */
> > -  (inquiry) MesosSchedulerDriverImpl_clear,         /* tp_clear */
> > -  0,                                                /* tp_richcompare */
> > -  0,                                                /* tp_weaklistoffset
> > */
> > -  0,                                                /* tp_iter */
> > -  0,                                                /* tp_iternext */
> > -  MesosSchedulerDriverImpl_methods,                 /* tp_methods */
> > -  0,                                                /* tp_members */
> > -  0,                                                /* tp_getset */
> > -  0,                                                /* tp_base */
> > -  0,                                                /* tp_dict */
> > -  0,                                                /* tp_descr_get */
> > -  0,                                                /* tp_descr_set */
> > -  0,                                                /* tp_dictoffset */
> > -  (initproc) MesosSchedulerDriverImpl_init,         /* tp_init */
> > -  0,                                                /* tp_alloc */
> > -  MesosSchedulerDriverImpl_new,                     /* tp_new */
> > -};
> > -
> > -
> > -/**
> > - * List of Python methods in MesosSchedulerDriverImpl.
> > - */
> > -PyMethodDef MesosSchedulerDriverImpl_methods[] = {
> > -  { "start",
> > -    (PyCFunction) MesosSchedulerDriverImpl_start,
> > -    METH_NOARGS,
> > -    "Start the driver to connect to Mesos"
> > -  },
> > -  { "stop",
> > -    (PyCFunction) MesosSchedulerDriverImpl_stop,
> > -    METH_VARARGS,
> > -    "Stop the driver, disconnecting from Mesos"
> > -  },
> > -  { "abort",
> > -    (PyCFunction) MesosSchedulerDriverImpl_abort,
> > -    METH_NOARGS,
> > -    "Abort the driver, disabling calls from and to the driver"
> > -  },
> > -  { "join",
> > -    (PyCFunction) MesosSchedulerDriverImpl_join,
> > -    METH_NOARGS,
> > -    "Wait for a running driver to disconnect from Mesos"
> > -  },
> > -  { "run",
> > -    (PyCFunction) MesosSchedulerDriverImpl_run,
> > -    METH_NOARGS,
> > -    "Start a driver and run it, returning when it disconnects from
> Mesos"
> > -  },
> > -  { "requestResources",
> > -    (PyCFunction) MesosSchedulerDriverImpl_requestResources,
> > -    METH_VARARGS,
> > -    "Request resources from the Mesos allocator"
> > -  },
> > -  { "launchTasks",
> > -    (PyCFunction) MesosSchedulerDriverImpl_launchTasks,
> > -    METH_VARARGS,
> > -    "Reply to a Mesos offer with a list of tasks"
> > -  },
> > -  { "killTask",
> > -    (PyCFunction) MesosSchedulerDriverImpl_killTask,
> > -    METH_VARARGS,
> > -    "Kill the task with the given ID"
> > -  },
> > -  { "acceptOffers",
> > -    (PyCFunction) MesosSchedulerDriverImpl_acceptOffers,
> > -    METH_VARARGS,
> > -    "Reply to a Mesos offer with a list of offer operations"
> > -  },
> > -  { "declineOffer",
> > -    (PyCFunction) MesosSchedulerDriverImpl_declineOffer,
> > -    METH_VARARGS,
> > -    "Decline a Mesos offer"
> > -  },
> > -  { "reviveOffers",
> > -    (PyCFunction) MesosSchedulerDriverImpl_reviveOffers,
> > -    METH_NOARGS,
> > -    "Remove all filters and ask Mesos for new offers"
> > -  },
> > -  { "suppressOffers",
> > -    (PyCFunction) MesosSchedulerDriverImpl_suppressOffers,
> > -    METH_NOARGS,
> > -    "Set suppressed attribute as true for the Framework"
> > -  },
> > -  { "acknowledgeStatusUpdate",
> > -    (PyCFunction) MesosSchedulerDriverImpl_acknowledgeStatusUpdate,
> > -    METH_VARARGS,
> > -    "Acknowledge a status update"
> > -  },
> > -  { "sendFrameworkMessage",
> > -    (PyCFunction) MesosSchedulerDriverImpl_sendFrameworkMessage,
> > -    METH_VARARGS,
> > -    "Send a FrameworkMessage to a slave"
> > -  },
> > -  { "reconcileTasks",
> > -    (PyCFunction) MesosSchedulerDriverImpl_reconcileTasks,
> > -    METH_VARARGS,
> > -    "Master sends status updates if task status is different from
> > expected"
> > -  },
> > -  { NULL }  /* Sentinel */
> > -};
> > -
> > -
> > -/**
> > - * Create, but don't initialize, a new MesosSchedulerDriverImpl
> > - * (called by Python before init method).
> > - */
> > -PyObject* MesosSchedulerDriverImpl_new(PyTypeObject* type,
> > -                                       PyObject* args,
> > -                                       PyObject* kwds)
> > -{
> > -  MesosSchedulerDriverImpl* self;
> > -  self = (MesosSchedulerDriverImpl*) type->tp_alloc(type, 0);
> > -  if (self != NULL) {
> > -    self->driver = NULL;
> > -    self->proxyScheduler = NULL;
> > -    self->pythonScheduler = NULL;
> > -  }
> > -  return (PyObject*) self;
> > -}
> > -
> > -
> > -/**
> > - * Initialize a MesosSchedulerDriverImpl with constructor arguments.
> > - */
> > -int MesosSchedulerDriverImpl_init(MesosSchedulerDriverImpl* self,
> > -                                  PyObject* args,
> > -                                  PyObject* kwds)
> > -{
> > -  // Note: We use an integer for 'implicitAcknoweldgements' because
> > -  // it is the recommended way to pass booleans through CPython.
> > -  PyObject* schedulerObj = NULL;
> > -  PyObject* frameworkObj = NULL;
> > -  const char* master;
> > -  int implicitAcknowledgements = 1; // Enabled by default.
> > -  PyObject* credentialObj = NULL;
> > -
> > -  if (!PyArg_ParseTuple(
> > -      args,
> > -      "OOs|iO",
> > -      &schedulerObj,
> > -      &frameworkObj,
> > -      &master,
> > -      &implicitAcknowledgements,
> > -      &credentialObj)) {
> > -    return -1;
> > -  }
> > -
> > -  if (schedulerObj != NULL) {
> > -    PyObject* tmp = self->pythonScheduler;
> > -    Py_INCREF(schedulerObj);
> > -    self->pythonScheduler = schedulerObj;
> > -    Py_XDECREF(tmp);
> > -  }
> > -
> > -  FrameworkInfo framework;
> > -  if (frameworkObj != NULL) {
> > -    if (!readPythonProtobuf(frameworkObj, &framework)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python FrameworkInfo");
> > -      return -1;
> > -    }
> > -  }
> > -
> > -  Credential credential;
> > -  if (credentialObj != NULL) {
> > -    if (!readPythonProtobuf(credentialObj, &credential)) {
> > -      PyErr_Format(PyExc_Exception, "Could not deserialize Python
> > Credential");
> > -      return -1;
> > -    }
> > -  }
> > -
> > -
> > -  if (self->driver != NULL) {
> > -    delete self->driver;
> > -    self->driver = NULL;
> > -  }
> > -
> > -  if (self->proxyScheduler != NULL) {
> > -    delete self->proxyScheduler;
> > -    self->proxyScheduler = NULL;
> > -  }
> > -
> > -  self->proxyScheduler = new ProxyScheduler(self);
> > -
> > -  if (credentialObj != NULL) {
> > -    self->driver = new MesosSchedulerDriver(
> > -        self->proxyScheduler,
> > -        framework,
> > -        master,
> > -        implicitAcknowledgements != 0,
> > -        credential);
> > -  } else {
> > -    self->driver = new MesosSchedulerDriver(
> > -        self->proxyScheduler,
> > -        framework,
> > -        master,
> > -        implicitAcknowledgements != 0);
> > -  }
> > -
> > -  return 0;
> > -}
> > -
> > -
> > -/**
> > - * Free a MesosSchedulerDriverImpl.
> > - */
> > -void MesosSchedulerDriverImpl_dealloc(MesosSchedulerDriverImpl* self)
> > -{
> > -  if (self->driver != NULL) {
> > -    // We need to wrap the driver destructor in an "allow threads"
> > -    // macro since the MesosSchedulerDriver destructor waits for the
> > -    // SchedulerProcess to terminate and there might be a thread that
> > -    // is trying to acquire the GIL to call through the
> > -    // ProxyScheduler. It will only be after this thread executes that
> > -    // the SchedulerProcess might actually get a terminate.
> > -    Py_BEGIN_ALLOW_THREADS
> > -    delete self->driver;
> > -    Py_END_ALLOW_THREADS
> > -    self->driver = NULL;
> > -  }
> > -
> > -  if (self->proxyScheduler != NULL) {
> > -    delete self->proxyScheduler;
> > -    self->proxyScheduler = NULL;
> > -  }
> > -
> > -  MesosSchedulerDriverImpl_clear(self);
> > -  self->ob_type->tp_free((PyObject*) self);
> > -}
> > -
> > -
> > -/**
> > - * Traverse fields of a MesosSchedulerDriverImpl on a cyclic GC search.
> > - * See http://docs.python.org/extending/newtypes.html.
> > - */
> > -int MesosSchedulerDriverImpl_traverse(MesosSchedulerDriverImpl* self,
> > -                                      visitproc visit,
> > -                                      void* arg)
> > -{
> > -  Py_VISIT(self->pythonScheduler);
> > -  return 0;
> > -}
> > -
> > -
> > -/**
> > - * Clear fields of a MesosSchedulerDriverImpl that can participate in
> > - * GC cycles. See http://docs.python.org/extending/newtypes.html.
> > - */
> > -int MesosSchedulerDriverImpl_clear(MesosSchedulerDriverImpl* self)
> > -{
> > -  Py_CLEAR(self->pythonScheduler);
> > -  return 0;
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_start(MesosSchedulerDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->start();
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_stop(MesosSchedulerDriverImpl* self,
> > -                                        PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  bool failover = false; // Should match default in mesos.py.
> > -
> > -  if (!PyArg_ParseTuple(args, "|b", &failover)) {
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->stop(failover);
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_abort(MesosSchedulerDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->abort();
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_join(MesosSchedulerDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status;
> > -  Py_BEGIN_ALLOW_THREADS
> > -  status = self->driver->join();
> > -  Py_END_ALLOW_THREADS
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_run(MesosSchedulerDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status;
> > -  Py_BEGIN_ALLOW_THREADS
> > -  status = self->driver->run();
> > -  Py_END_ALLOW_THREADS
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_requestResources(
> > -    MesosSchedulerDriverImpl* self,
> > -    PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* requestsObj = NULL;
> > -  vector<Request> requests;
> > -
> > -  if (!PyArg_ParseTuple(args, "O", &requestsObj)) {
> > -    return NULL;
> > -  }
> > -
> > -  if (!PyList_Check(requestsObj)) {
> > -    PyErr_Format(PyExc_Exception,
> > -                 "Parameter 2 to requestsResources is not a list");
> > -    return NULL;
> > -  }
> > -  Py_ssize_t len = PyList_Size(requestsObj);
> > -  for (int i = 0; i < len; i++) {
> > -    PyObject* requestObj = PyList_GetItem(requestsObj, i);
> > -    if (requestObj == NULL) {
> > -      return NULL; // Exception will have been set by PyList_GetItem.
> > -    }
> > -    Request request;
> > -    if (!readPythonProtobuf(requestObj, &request)) {
> > -      PyErr_Format(PyExc_Exception, "Could not deserialize Python
> > Request");
> > -      return NULL;
> > -    }
> > -    requests.push_back(request);
> > -  }
> > -
> > -  Status status = self->driver->requestResources(requests);
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_launchTasks(MesosSchedulerDriverImpl*
> > self,
> > -                                                PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* offerIdsObj = NULL;
> > -  PyObject* tasksObj = NULL;
> > -  PyObject* filtersObj = NULL;
> > -  vector<OfferID> offerIds;
> > -  vector<TaskInfo> tasks;
> > -  Filters filters;
> > -
> > -  if (!PyArg_ParseTuple(args, "OO|O", &offerIdsObj, &tasksObj,
> > &filtersObj)) {
> > -    return NULL;
> > -  }
> > -
> > -  // Offer argument can be a list of offer ids or a single offer id (for
> > -  // backward compatibility).
> > -  if (!PyList_Check(offerIdsObj)) {
> > -    OfferID offerId;
> > -    if (!readPythonProtobuf(offerIdsObj, &offerId)) {
> > -      PyErr_Format(PyExc_Exception, "Could not deserialize Python
> > OfferID");
> > -      return NULL;
> > -    }
> > -    offerIds.push_back(offerId);
> > -  } else {
> > -    Py_ssize_t len = PyList_Size(offerIdsObj);
> > -    for (int i = 0; i < len; i++) {
> > -      PyObject* offerObj = PyList_GetItem(offerIdsObj, i);
> > -      if (offerObj == NULL) {
> > -        return NULL;
> > -      }
> > -      OfferID offerId;
> > -      if (!readPythonProtobuf(offerObj, &offerId)) {
> > -        PyErr_Format(PyExc_Exception,
> > -                     "Could not deserialize Python OfferID");
> > -        return NULL;
> > -      }
> > -      offerIds.push_back(offerId);
> > -    }
> > -  }
> > -
> > -  if (!PyList_Check(tasksObj)) {
> > -    PyErr_Format(PyExc_Exception, "Parameter 2 to launchTasks is not a
> > list");
> > -    return NULL;
> > -  }
> > -  Py_ssize_t len = PyList_Size(tasksObj);
> > -  for (int i = 0; i < len; i++) {
> > -    PyObject* taskObj = PyList_GetItem(tasksObj, i);
> > -    if (taskObj == NULL) {
> > -      return NULL; // Exception will have been set by PyList_GetItem.
> > -    }
> > -    TaskInfo task;
> > -    if (!readPythonProtobuf(taskObj, &task)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python TaskInfo");
> > -      return NULL;
> > -    }
> > -    tasks.push_back(task);
> > -  }
> > -
> > -  if (filtersObj != NULL) {
> > -    if (!readPythonProtobuf(filtersObj, &filters)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python Filters");
> > -      return NULL;
> > -    }
> > -  }
> > -
> > -  Status status = self->driver->launchTasks(offerIds, tasks, filters);
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_killTask(MesosSchedulerDriverImpl*
> > self,
> > -                                            PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* tidObj = NULL;
> > -  TaskID tid;
> > -  if (!PyArg_ParseTuple(args, "O", &tidObj)) {
> > -    return NULL;
> > -  }
> > -  if (!readPythonProtobuf(tidObj, &tid)) {
> > -    PyErr_Format(PyExc_Exception, "Could not deserialize Python
> TaskID");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->killTask(tid);
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject*
> MesosSchedulerDriverImpl_acceptOffers(MesosSchedulerDriverImpl*
> > self,
> > -                                                PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* offerIdsObj = NULL;
> > -  PyObject* operationsObj = NULL;
> > -  PyObject* filtersObj = NULL;
> > -  Py_ssize_t len = 0;
> > -  vector<OfferID> offerIds;
> > -  vector<Offer::Operation> operations;
> > -  Filters filters;
> > -
> > -  if (!PyArg_ParseTuple(args,
> > -                        "OO|O",
> > -                        &offerIdsObj,
> > -                        &operationsObj,
> > -                        &filtersObj)) {
> > -    return NULL;
> > -  }
> > -
> > -  if (!PyList_Check(offerIdsObj)) {
> > -    PyErr_Format(PyExc_Exception, "Parameter 1 to acceptOffers is not a
> > list");
> > -    return NULL;
> > -  }
> > -
> > -  len = PyList_Size(offerIdsObj);
> > -  for (int i = 0; i < len; i++) {
> > -    PyObject* offerObj = PyList_GetItem(offerIdsObj, i);
> > -    if (offerObj == NULL) {
> > -      return NULL;
> > -    }
> > -
> > -    OfferID offerId;
> > -    if (!readPythonProtobuf(offerObj, &offerId)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python OfferID");
> > -      return NULL;
> > -    }
> > -    offerIds.push_back(offerId);
> > -  }
> > -
> > -  if (!PyList_Check(operationsObj)) {
> > -    PyErr_Format(PyExc_Exception, "Parameter 2 to acceptOffers is not a
> > list");
> > -    return NULL;
> > -  }
> > -
> > -  len = PyList_Size(operationsObj);
> > -  for (int i = 0; i < len; i++) {
> > -    PyObject* operationObj = PyList_GetItem(operationsObj, i);
> > -    if (operationObj == NULL) {
> > -      return NULL; // Exception will have been set by PyList_GetItem.
> > -    }
> > -
> > -    Offer::Operation operation;
> > -    if (!readPythonProtobuf(operationObj, &operation)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python Offer.Operation");
> > -      return NULL;
> > -    }
> > -    operations.push_back(operation);
> > -  }
> > -
> > -  if (filtersObj != NULL) {
> > -    if (!readPythonProtobuf(filtersObj, &filters)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python Filters");
> > -      return NULL;
> > -    }
> > -  }
> > -
> > -  Status status = self->driver->acceptOffers(offerIds, operations,
> > filters);
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject*
> MesosSchedulerDriverImpl_declineOffer(MesosSchedulerDriverImpl*
> > self,
> > -                                                PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* offerIdObj = NULL;
> > -  PyObject* filtersObj = NULL;
> > -  OfferID offerId;
> > -  Filters filters;
> > -
> > -  if (!PyArg_ParseTuple(args, "O|O", &offerIdObj, &filtersObj)) {
> > -    return NULL;
> > -  }
> > -
> > -  if (!readPythonProtobuf(offerIdObj, &offerId)) {
> > -    PyErr_Format(PyExc_Exception, "Could not deserialize Python
> OfferID");
> > -    return NULL;
> > -  }
> > -
> > -  if (filtersObj != NULL) {
> > -    if (!readPythonProtobuf(filtersObj, &filters)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python Filters");
> > -      return NULL;
> > -    }
> > -  }
> > -
> > -  Status status = self->driver->declineOffer(offerId, filters);
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject*
> MesosSchedulerDriverImpl_reviveOffers(MesosSchedulerDriverImpl*
> > self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->reviveOffers();
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_suppressOffers(
> > -    MesosSchedulerDriverImpl* self)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->suppressOffers();
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_acknowledgeStatusUpdate(
> > -    MesosSchedulerDriverImpl* self,
> > -    PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* taskStatusObj = NULL;
> > -  TaskStatus taskStatus;
> > -
> > -  if (!PyArg_ParseTuple(args, "O", &taskStatusObj)) {
> > -    return NULL;
> > -  }
> > -
> > -  if (!readPythonProtobuf(taskStatusObj, &taskStatus)) {
> > -    PyErr_Format(PyExc_Exception, "Could not deserialize Python
> > TaskStatus");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->acknowledgeStatusUpdate(taskStatus);
> > -
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_sendFrameworkMessage(
> > -    MesosSchedulerDriverImpl* self,
> > -    PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* slaveIdObj = NULL;
> > -  PyObject* executorIdObj = NULL;
> > -  SlaveID slaveId;
> > -  ExecutorID executorId;
> > -  const char* data;
> > -  int length;
> > -
> > -  if (!PyArg_ParseTuple(
> > -      args, "OOs#", &executorIdObj, &slaveIdObj, &data, &length)) {
> > -    return NULL;
> > -  }
> > -
> > -  if (!readPythonProtobuf(executorIdObj, &executorId)) {
> > -    PyErr_Format(PyExc_Exception, "Could not deserialize Python
> > ExecutorID");
> > -    return NULL;
> > -  }
> > -
> > -  if (!readPythonProtobuf(slaveIdObj, &slaveId)) {
> > -    PyErr_Format(PyExc_Exception, "Could not deserialize Python
> SlaveID");
> > -    return NULL;
> > -  }
> > -
> > -  Status status = self->driver->sendFrameworkMessage(
> > -      executorId, slaveId, string(data, length));
> > -
> > -  return PyInt_FromLong(status); // Sets exception if creating long
> fails.
> > -}
> > -
> > -
> > -PyObject* MesosSchedulerDriverImpl_reconcileTasks(
> > -    MesosSchedulerDriverImpl* self,
> > -    PyObject* args)
> > -{
> > -  if (self->driver == NULL) {
> > -    PyErr_Format(PyExc_Exception, "MesosSchedulerDriverImpl.driver is
> > NULL");
> > -    return NULL;
> > -  }
> > -
> > -  PyObject* statusesObj = NULL;
> > -  vector<TaskStatus> statuses;
> > -
> > -  if (!PyArg_ParseTuple(args, "O", &statusesObj)) {
> > -    return NULL;
> > -  }
> > -
> > -  if (!PyList_Check(statusesObj)) {
> > -    PyErr_Format(PyExc_Exception,
> > -      "Parameter 1 to reconcileTasks is not a list");
> > -
> > -    return NULL;
> > -  }
> > -
> > -  Py_ssize_t len = PyList_Size(statusesObj);
> > -  for (int i = 0; i < len; i++) {
> > -    PyObject* statusObj = PyList_GetItem(statusesObj, i);
> > -    if (statusObj == NULL) {
> > -      return NULL;
> > -    }
> > -
> > -    TaskStatus status;
> > -    if (!readPythonProtobuf(statusObj, &status)) {
> > -      PyErr_Format(PyExc_Exception,
> > -                   "Could not deserialize Python TaskStatus");
> > -      return NULL;
> > -    }
> > -    statuses.push_back(status);
> > -  }
> > -
> > -  Status status = self->driver->reconcileTasks(statuses);
> > -  return PyInt_FromLong(status);
> > -}
> > -
> > -} // namespace python {
> > -} // namespace mesos {
> >
> >
>



-- 
Best Regards,
Haosdent Huang

Reply via email to