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. SQLAlchemy使用(三)搭配Flask框架使用

    前言 本章应该是SQLAlchemy使用系列的最后一篇了,本章简单讲一下如何搭配Flask使用.下一篇应该是写Flask_restful相关内容了 正文 我们简单使用前两章的model,两张表 # - ...

  2. C - BLG POJ - 1417 种类并查集加dp(背包)

    思路:刚看这道题感觉什么都不清楚,人物之间的关系一点也看不出来,都不知道怎么写,连并查集都没看出来,但是你可以仔细分析一下,当输入字符串为“yes”的时候,我们设输入的值为x和y,当x为天使是则由题可 ...

  3. 清晰讲解SQL语句中的内连接,通用于Mysql和Oracle,全是干货哦

    本文章目的:力求清晰明了讲解SQL语句的内连接的各种应用,没有深奥的理解! 前奏:这篇文章和下篇文章会将内连接和外连接讲解清楚SQL语句的多表查询常用的有以下几种:两表联合查询(1)内连接(2)外连接 ...

  4. 网络流24题——骑士共存问题 luogu 3355

    题目描述:这里 从这里开始,我们涉及到了一个新的问题:最小割问题 首先给出一些定义(本人根据定义自己口胡的): 一个流网络中的一个割是一个边集,使得割掉这些边集后源点与汇点不连通 而最小割问题就是一个 ...

  5. Centos7源码安装mariadb

    mariadb官网:http://mirrors.opencas.cn/mariadb 安装开发工具: yum grouplist yum groupinstall "Development ...

  6. MySQL查看所有连接的客户端ip

    ) AS host_name,state,count(*) FROM information_schema.processlist GROUP BY state,host_name;

  7. 558. Quad Tree Intersection

    https://leetcode.com/problems/quad-tree-intersection/description/ 我觉得是用意挺好的一题目.求两个四叉树的逻辑union,可惜测试用例 ...

  8. 16 道嵌入式C语言面试题

    1. 用预处理指令#define 声明一个常数,用以表明 1 年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到 ...

  9. c/c++再学习:C++中public、protect、private的访问权限控制

    C++中public.protect.private的访问权限控制 访问权限 一个类的public成员变量.成员函数,可以通过类的成员函数.类的实例变量进行访问 一个类的protected成员变量.成 ...

  10. RESTful-1概述

    一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制. 概述 编辑 REST ...