Test Executor的代码在src/examples/test_executor.cpp中

 

  1. int main(int argc, char** argv)
  2. {
  3.   TestExecutor executor;
  4.   MesosExecutorDriver driver(&executor);
  5.   return driver.run() == DRIVER_STOPPED ? 0 : 1;
  6. }

 

Executor的运行主要依赖于MesosExecutorDriver作为封装,和mesos-slave进行通信。

 

MesosExecutorDriver的实现在src/exec/exec.cpp中

 

  1. Status MesosExecutorDriver::run()
  2. {
  3.   Status status = start();
  4.   return status != DRIVER_RUNNING ? status : join();
  5. }

 

  1. Status MesosExecutorDriver::start()
  2. {
  3.   synchronized (mutex) {
  4.     if (status != DRIVER_NOT_STARTED) {
  5.       return status;
  6.     }
  7.  
  8.     // Set stream buffering mode to flush on newlines so that we
  9.     // capture logs from user processes even when output is redirected
  10.     // to a file.
  11.     setvbuf(stdout, 0, _IOLBF, 0);
  12.     setvbuf(stderr, 0, _IOLBF, 0);
  13.  
  14.     bool local;
  15.  
  16.     UPID slave;
  17.     SlaveID slaveId;
  18.     FrameworkID frameworkId;
  19.     ExecutorID executorId;
  20.     string workDirectory;
  21.     bool checkpoint;
  22.  
  23.     Option<string> value;
  24.     std::istringstream iss;
  25.  
  26.     // Check if this is local (for example, for testing).
  27.     local = os::getenv("MESOS_LOCAL").isSome();
  28.  
  29.     // Get slave PID from environment.
  30.     value = os::getenv("MESOS_SLAVE_PID");
  31.     if (value.isNone()) {
  32.       EXIT(EXIT_FAILURE)
  33.         << "Expecting 'MESOS_SLAVE_PID' to be set in the environment";
  34.     }
  35.  
  36.     slave = UPID(value.get());
  37.     CHECK(slave) << "Cannot parse MESOS_SLAVE_PID '" << value.get() << "'";
  38.  
  39.     // Get slave ID from environment.
  40.     value = os::getenv("MESOS_SLAVE_ID");
  41.     if (value.isNone()) {
  42.       EXIT(EXIT_FAILURE)
  43.         << "Expecting 'MESOS_SLAVE_ID' to be set in the environment";
  44.     }
  45.     slaveId.set_value(value.get());
  46.  
  47.     // Get framework ID from environment.
  48.     value = os::getenv("MESOS_FRAMEWORK_ID");
  49.     if (value.isNone()) {
  50.       EXIT(EXIT_FAILURE)
  51.         << "Expecting 'MESOS_FRAMEWORK_ID' to be set in the environment";
  52.     }
  53.     frameworkId.set_value(value.get());
  54.  
  55.     // Get executor ID from environment.
  56.     value = os::getenv("MESOS_EXECUTOR_ID");
  57.     if (value.isNone()) {
  58.       EXIT(EXIT_FAILURE)
  59.         << "Expecting 'MESOS_EXECUTOR_ID' to be set in the environment";
  60.     }
  61.     executorId.set_value(value.get());
  62.  
  63.     // Get working directory from environment.
  64.     value = os::getenv("MESOS_DIRECTORY");
  65.     if (value.isNone()) {
  66.       EXIT(EXIT_FAILURE)
  67.         << "Expecting 'MESOS_DIRECTORY' to be set in the environment";
  68.     }
  69.     workDirectory = value.get();
  70.  
  71.     // Get checkpointing status from environment.
  72.     value = os::getenv("MESOS_CHECKPOINT");
  73.     checkpoint = ";
  74.  
  75.     Duration recoveryTimeout = RECOVERY_TIMEOUT;
  76.  
  77.     // Get the recovery timeout if checkpointing is enabled.
  78.     if (checkpoint) {
  79.       value = os::getenv("MESOS_RECOVERY_TIMEOUT");
  80.  
  81.       if (value.isSome()) {
  82.         Try<Duration> _recoveryTimeout = Duration::parse(value.get());
  83.  
  84.         if (_recoveryTimeout.isError()) {
  85.           EXIT(EXIT_FAILURE)
  86.             << "Cannot parse MESOS_RECOVERY_TIMEOUT '" << value.get() << "': "
  87.             << _recoveryTimeout.error();
  88.         }
  89.  
  90.         recoveryTimeout = _recoveryTimeout.get();
  91.       }
  92.     }
  93.  
  94.     CHECK(process == NULL);
  95.  
  96.     process = new ExecutorProcess(
  97.         slave,
  98.         this,
  99.         executor,
  100.         slaveId,
  101.         frameworkId,
  102.         executorId,
  103.         local,
  104.         workDirectory,
  105.         checkpoint,
  106.         recoveryTimeout,
  107.         &mutex,
  108.         latch);
  109.  
  110.     spawn(process);
  111.  
  112.     return status = DRIVER_RUNNING;
  113.   }
  114. }

 

启动另一个线程ExecutorProcess,它的构造函数如下,注册了很多消息处理函数。

 

  1. ExecutorProcess(const UPID& _slave,
  2.                 MesosExecutorDriver* _driver,
  3.                 Executor* _executor,
  4.                 const SlaveID& _slaveId,
  5.                 const FrameworkID& _frameworkId,
  6.                 const ExecutorID& _executorId,
  7.                 bool _local,
  8.                 const
    string& _directory,
  9.                 bool _checkpoint,
  10.                 Duration _recoveryTimeout,
  11.                 std::recursive_mutex* _mutex,
  12.                 Latch* _latch)
  13.   : ProcessBase(ID::generate("executor")),
  14.     slave(_slave),
  15.     driver(_driver),
  16.     executor(_executor),
  17.     slaveId(_slaveId),
  18.     frameworkId(_frameworkId),
  19.     executorId(_executorId),
  20.     connected(false),
  21.     connection(UUID::random()),
  22.     local(_local),
  23.     aborted(false),
  24.     mutex(_mutex),
  25.     latch(_latch),
  26.     directory(_directory),
  27.     checkpoint(_checkpoint),
  28.     recoveryTimeout(_recoveryTimeout)
  29. {
  30.   LOG(INFO) << "Version: " << MESOS_VERSION;
  31.  
  32.   install<ExecutorRegisteredMessage>(
  33.       &ExecutorProcess::registered,
  34.       &ExecutorRegisteredMessage::executor_info,
  35.       &ExecutorRegisteredMessage::framework_id,
  36.       &ExecutorRegisteredMessage::framework_info,
  37.       &ExecutorRegisteredMessage::slave_id,
  38.       &ExecutorRegisteredMessage::slave_info);
  39.  
  40.   install<ExecutorReregisteredMessage>(
  41.       &ExecutorProcess::reregistered,
  42.       &ExecutorReregisteredMessage::slave_id,
  43.       &ExecutorReregisteredMessage::slave_info);
  44.  
  45.   install<ReconnectExecutorMessage>(
  46.       &ExecutorProcess::reconnect,
  47.       &ReconnectExecutorMessage::slave_id);
  48.  
  49.   install<RunTaskMessage>(
  50.       &ExecutorProcess::runTask,
  51.       &RunTaskMessage::task);
  52.  
  53.   install<KillTaskMessage>(
  54.       &ExecutorProcess::killTask,
  55.       &KillTaskMessage::task_id);
  56.  
  57.   install<StatusUpdateAcknowledgementMessage>(
  58.       &ExecutorProcess::statusUpdateAcknowledgement,
  59.       &StatusUpdateAcknowledgementMessage::slave_id,
  60.       &StatusUpdateAcknowledgementMessage::framework_id,
  61.       &StatusUpdateAcknowledgementMessage::task_id,
  62.       &StatusUpdateAcknowledgementMessage::uuid);
  63.  
  64.   install<FrameworkToExecutorMessage>(
  65.       &ExecutorProcess::frameworkMessage,
  66.       &FrameworkToExecutorMessage::slave_id,
  67.       &FrameworkToExecutorMessage::framework_id,
  68.       &FrameworkToExecutorMessage::executor_id,
  69.       &FrameworkToExecutorMessage::data);
  70.  
  71.   install<ShutdownExecutorMessage>(
  72.       &ExecutorProcess::shutdown);
  73. }

 

在ExecutorProcess的initiailize的函数中,向mesos-slave发送消息进行注册。

  1. virtual
    void initialize()
  2. {
  3.   VLOG(1) << "Executor started at: " << self()
  4.           << " with pid " << getpid();
  5.  
  6.   link(slave);
  7.  
  8.   // Register with slave.
  9.   RegisterExecutorMessage message;
  10.   message.mutable_framework_id()->MergeFrom(frameworkId);
  11.   message.mutable_executor_id()->MergeFrom(executorId);
  12.   send(slave, message);
  13. }

 

当Mesos-slave向TestExecutor发送RunTaskMessage消息的时候,ExecutorProcess调用runTask函数。

  1. void runTask(const TaskInfo& task)
  2. {
  3.   if (aborted.load()) {
  4.     VLOG(1) << "Ignoring run task message for task " << task.task_id()
  5.             << " because the driver is aborted!";
  6.     return;
  7.   }
  8.  
  9.   CHECK(!tasks.contains(task.task_id()))
  10.     << "Unexpected duplicate task " << task.task_id();
  11.  
  12.   tasks[task.task_id()] = task;
  13.  
  14.   VLOG(1) << "Executor asked to run task '" << task.task_id() << "'";
  15.  
  16.   Stopwatch stopwatch;
  17.   if (FLAGS_v >= 1) {
  18.     stopwatch.start();
  19.   }
  20.  
  21.   executor->launchTask(driver, task);
  22.  
  23.   VLOG(1) << "Executor::launchTask took " << stopwatch.elapsed();
  24. }

 

最终调用executor的launchTask

在src/examples/test_executor.cpp中

  1. virtual
    void launchTask(ExecutorDriver* driver, const TaskInfo& task)
  2. {
  3.   cout << "Starting task " << task.task_id().value() << endl;
  4.  
  5.   TaskStatus status;
  6.   status.mutable_task_id()->MergeFrom(task.task_id());
  7.   status.set_state(TASK_RUNNING);
  8.  
  9.   driver->sendStatusUpdate(status);
  10.  
  11.   // This is where one would perform the requested task.
  12.  
  13.   cout << "Finishing task " << task.task_id().value() << endl;
  14.  
  15.   status.mutable_task_id()->MergeFrom(task.task_id());
  16.   status.set_state(TASK_FINISHED);
  17.  
  18.   driver->sendStatusUpdate(status);
  19. }

Mesos源码分析(15): Test Executor的运行的更多相关文章

  1. Mesos源码分析

    Mesos源码分析(1): Mesos的启动过程总论 Mesos源码分析(2): Mesos Master的启动之一 Mesos源码分析(3): Mesos Master的启动之二 Mesos源码分析 ...

  2. Mesos源码分析(12): Mesos-Slave接收到RunTask消息

    在前文Mesos源码分析(8): Mesos-Slave的初始化中,Mesos-Slave接收到RunTaskMessage消息,会调用Slave::runTask.   void Slave::ru ...

  3. Mesos源码分析(11): Mesos-Master接收到launchTasks消息

    根据Mesos源码分析(6): Mesos Master的初始化中的代码分析,当Mesos-Master接收到launchTask消息的时候,会调用Master::launchTasks函数.   v ...

  4. Mesos源码分析(10): MesosSchedulerDriver的启动及运行一个Task

      MesosSchedulerDriver的代码在src/sched/sched.cpp里面实现.     Driver->run()调用start()     首先检测Mesos-Maste ...

  5. Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2)

    Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2) 上一节主要介绍了SolrCloud分布式索引的整体流程图以及索引链的实现,那么本节开始将分别介绍三个索引过程即LogUpdat ...

  6. Mesos源码分析(5): Mesos Master的启动之四

      5. Create an instance of allocator.   代码如下   Mesos源码中默认的Allocator,即HierarchicalDRFAllocator的位置在$ME ...

  7. Spark RPC框架源码分析(二)RPC运行时序

    前情提要: Spark RPC框架源码分析(一)简述 一. Spark RPC概述 上一篇我们已经说明了Spark RPC框架的一个简单例子,Spark RPC相关的两个编程模型,Actor模型和Re ...

  8. Spark源码分析之一:Job提交运行总流程概述

    Spark是一个基于内存的分布式计算框架,运行在其上的应用程序,按照Action被划分为一个个Job,而Job提交运行的总流程,大致分为两个阶段: 1.Stage划分与提交 (1)Job按照RDD之间 ...

  9. Mesos源码分析(16): mesos-docker-executor的运行

    mesos-docker-executor的运行代码在src/docker/executor.cpp中   int main(int argc, char** argv) {   GOOGLE_PRO ...

随机推荐

  1. JAVA 三元运算符 求最大值

    package Code428; import java.util.Scanner; public class CodeScannerMax { public static void main(Str ...

  2. linux shell脚本、命令学习

    1,echo "test" > test.txt    输出重定向到text.txt,文件不存在就创建 echo "test" >> test ...

  3. Lesson 1-2

    1.5 模块 模块可视为扩展,通过将其导入可以扩展python的功能.python中自带有一组模块,也称为“标准库”. 1.5.1 模块的导入:import + 模块名称 • 使用关键字import导 ...

  4. PADS Layout VX.2.3 设置测量精度

    操作系统:Windows 10 x64 工具1:PADS Layout VX.2.3 Pin #7.#8的实际距离是0.65mm,但是测量的结果却是0.7mm.为什么呢?这是由于测量精度的设置不恰当造 ...

  5. [原创]Xilinx Vivado 2017.4/2018.3/2016.4/2015.4/ISE14.7下载及其安装

    最新版本Vivado 2018.3下载地址 链接:https://pan.baidu.com/s/17aE-vICRQYN27bD2sXCLxg提取码:ilg5 由于工程需要,下载VIVADO2018 ...

  6. mongodb导出数据到csv

    mongo cws export.js > out.csv export.js // Date.prototype.getIOSDate = function () { return new D ...

  7. EF Core 2.2 对多个 DbContext 单个数据库的情况进行迁移的示例

    目录 场景 创建新项目 创建第一个模型 创建第二个模型 使用依赖注入注册上下文 创建数据库 需要注意的情况 场景 在一个项目中,使用了多个 DbContext 且使用同一个数据库的情况 创建新项目 打 ...

  8. java中读取资源文件的方法

    展开全部 1.使用java.util.Properties类的load()方法 示例: //文件在项目下.不是在包下!! InputStream in = new BufferedInputStrea ...

  9. ubuntu 16.04 安装 vscode

    ubuntu 安装 vscode sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make sudo apt-get update sudo apt ...

  10. CentOS6.x 下 /etc/security/limits.conf 被改错的故障经历

    Intro 我司本小厂,每个员工都是身兼数职,所以开发人员直接登录线上服务器改东西是常态.有些开发人员,自持水平较高(的确水平也是较高,但缺乏对系统的敬畏),所以总是越俎代庖,改一些本身应该是线上运维 ...