You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/07/02 00:02:07 UTC
[5/6] mesos git commit: Refactored HealthCheck from a binary to be a
library.
Refactored HealthCheck from a binary to be a library.
Review: https://reviews.apache.org/r/49389/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1556d9a3
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1556d9a3
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1556d9a3
Branch: refs/heads/master
Commit: 1556d9a3a02de4e8a90b5b64d268754f95b12d77
Parents: c097509
Author: Gilbert Song <so...@gmail.com>
Authored: Fri Jul 1 17:01:50 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jul 1 17:01:50 2016 -0700
----------------------------------------------------------------------
src/CMakeLists.txt | 5 +
src/Makefile.am | 2 +
src/health-check/health_checker.cpp | 92 ++++++++++
src/health-check/health_checker.hpp | 294 +++++++++++++++++++++++++++++++
src/health-check/main.cpp | 229 +-----------------------
src/launcher/executor.cpp | 77 +++-----
6 files changed, 418 insertions(+), 281 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/1556d9a3/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 996d9e6..7f22a7c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -203,6 +203,10 @@ set(FILES_SRC
files/files.cpp
)
+set(HEALTH_CHECK_SRC
+ health-check/health_checker.cpp
+ )
+
set(HOOK_SRC
hook/manager.cpp
)
@@ -409,6 +413,7 @@ set(MESOS_SRC
${HOOK_SRC}
${INTERNAL_SRC}
${FILES_SRC}
+ ${HEALTH_CHECK_SRC}
${MESSAGES_SRC}
${LOGGING_SRC}
${VERSION_SRC}
http://git-wip-us.apache.org/repos/asf/mesos/blob/1556d9a3/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 72f8a99..52d63f2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -786,6 +786,7 @@ libmesos_no_3rdparty_la_SOURCES += \
executor/executor.cpp \
executor/v0_v1executor.cpp \
files/files.cpp \
+ health-check/health_checker.cpp \
hdfs/hdfs.cpp \
hook/manager.cpp \
internal/devolve.cpp \
@@ -906,6 +907,7 @@ libmesos_no_3rdparty_la_SOURCES += \
examples/utils.hpp \
executor/v0_v1executor.hpp \
files/files.hpp \
+ health-check/health_checker.hpp \
hdfs/hdfs.hpp \
hook/manager.hpp \
internal/devolve.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/1556d9a3/src/health-check/health_checker.cpp
----------------------------------------------------------------------
diff --git a/src/health-check/health_checker.cpp b/src/health-check/health_checker.cpp
new file mode 100644
index 0000000..585a0b5
--- /dev/null
+++ b/src/health-check/health_checker.cpp
@@ -0,0 +1,92 @@
+// 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.
+
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef __WINDOWS__
+#include <unistd.h>
+#endif // __WINDOWS__
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <mesos/mesos.hpp>
+
+#include <process/future.hpp>
+#include <process/pid.hpp>
+#include <process/process.hpp>
+#include <process/protobuf.hpp>
+
+#include <stout/protobuf.hpp>
+
+#include "health-check/health_checker.hpp"
+
+using namespace mesos;
+
+using process::UPID;
+
+namespace mesos {
+namespace internal {
+
+using namespace process;
+
+Try<Owned<HealthChecker>> HealthChecker::create(
+ const HealthCheck& check,
+ const UPID& executor,
+ const TaskID& taskID)
+{
+ // Validate the 'HealthCheck' protobuf.
+ if (check.has_http() && check.has_command()) {
+ return Error("Both 'http' and 'command' health check requested");
+ }
+
+ if (!check.has_http() && !check.has_command()) {
+ return Error("Expecting one of 'http' or 'command' health check");
+ }
+
+ Owned<HealthCheckerProcess> process(new HealthCheckerProcess(
+ check,
+ executor,
+ taskID));
+
+ return Owned<HealthChecker>(new HealthChecker(process));
+}
+
+
+HealthChecker::HealthChecker(
+ Owned<HealthCheckerProcess> _process)
+ : process(_process)
+{
+ spawn(CHECK_NOTNULL(process.get()));
+}
+
+
+HealthChecker::~HealthChecker()
+{
+ terminate(process.get());
+ wait(process.get());
+}
+
+
+Future<Nothing> HealthChecker::healthCheck()
+{
+ return dispatch(process.get(), &HealthCheckerProcess::healthCheck);
+}
+
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/1556d9a3/src/health-check/health_checker.hpp
----------------------------------------------------------------------
diff --git a/src/health-check/health_checker.hpp b/src/health-check/health_checker.hpp
new file mode 100644
index 0000000..f61e80d
--- /dev/null
+++ b/src/health-check/health_checker.hpp
@@ -0,0 +1,294 @@
+// 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 __HEALTH_CHECKER_HPP__
+#define __HEALTH_CHECKER_HPP__
+
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef __WINDOWS__
+#include <unistd.h>
+#endif // __WINDOWS__
+
+#include <iostream>
+#include <string>
+
+#include <mesos/mesos.hpp>
+
+#include <process/delay.hpp>
+#include <process/future.hpp>
+#include <process/pid.hpp>
+#include <process/process.hpp>
+#include <process/protobuf.hpp>
+#include <process/subprocess.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/flags.hpp>
+#include <stout/json.hpp>
+#include <stout/option.hpp>
+#include <stout/os.hpp>
+#include <stout/protobuf.hpp>
+#include <stout/strings.hpp>
+
+#include <stout/os/killtree.hpp>
+
+#include "common/status_utils.hpp"
+
+#include "messages/messages.hpp"
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::map;
+using std::string;
+
+using process::UPID;
+
+namespace mesos {
+namespace internal {
+
+// Forward declarations.
+class HealthCheckerProcess;
+
+class HealthChecker
+{
+public:
+ static Try<process::Owned<HealthChecker>> create(
+ const HealthCheck& check,
+ const UPID& executor,
+ const TaskID& taskID);
+
+ ~HealthChecker();
+
+ process::Future<Nothing> healthCheck();
+
+private:
+ explicit HealthChecker(process::Owned<HealthCheckerProcess> process);
+
+ process::Owned<HealthCheckerProcess> process;
+};
+
+
+class HealthCheckerProcess : public ProtobufProcess<HealthCheckerProcess>
+{
+public:
+ HealthCheckerProcess(
+ const HealthCheck& _check,
+ const UPID& _executor,
+ const TaskID& _taskID)
+ : check(_check),
+ initializing(true),
+ executor(_executor),
+ taskID(_taskID),
+ consecutiveFailures(0) {}
+
+ virtual ~HealthCheckerProcess() {}
+
+ process::Future<Nothing> healthCheck()
+ {
+ VLOG(2) << "Health checks starting in "
+ << Seconds(check.delay_seconds()) << ", grace period "
+ << Seconds(check.grace_period_seconds());
+
+ startTime = process::Clock::now();
+
+ delay(Seconds(check.delay_seconds()), self(), &Self::_healthCheck);
+ return promise.future();
+ }
+
+private:
+ void failure(const string& message)
+ {
+ if (check.grace_period_seconds() > 0 &&
+ (process::Clock::now() - startTime).secs() <=
+ check.grace_period_seconds()) {
+ LOG(INFO) << "Ignoring failure as health check still in grace period";
+ reschedule();
+ return;
+ }
+
+ consecutiveFailures++;
+ VLOG(1) << "#" << consecutiveFailures << " check failed: " << message;
+
+ bool killTask = consecutiveFailures >= check.consecutive_failures();
+
+ TaskHealthStatus taskHealthStatus;
+ taskHealthStatus.set_healthy(false);
+ taskHealthStatus.set_consecutive_failures(consecutiveFailures);
+ taskHealthStatus.set_kill_task(killTask);
+ taskHealthStatus.mutable_task_id()->CopyFrom(taskID);
+ send(executor, taskHealthStatus);
+
+ if (killTask) {
+ // This is a hack to ensure the message is sent to the
+ // executor before we exit the process. Without this,
+ // we may exit before libprocess has sent the data over
+ // the socket. See MESOS-4111.
+ os::sleep(Seconds(1));
+ promise.fail(message);
+ } else {
+ reschedule();
+ }
+ }
+
+ void success()
+ {
+ VLOG(1) << "Check passed";
+
+ // Send a healthy status update on the first success,
+ // and on the first success following failure(s).
+ if (initializing || consecutiveFailures > 0) {
+ TaskHealthStatus taskHealthStatus;
+ taskHealthStatus.set_healthy(true);
+ taskHealthStatus.mutable_task_id()->CopyFrom(taskID);
+ send(executor, taskHealthStatus);
+ initializing = false;
+ }
+ consecutiveFailures = 0;
+ reschedule();
+ }
+
+ void _healthCheck()
+ {
+ if (check.has_http()) {
+ promise.fail("HTTP health check is not supported");
+ return;
+ }
+
+ if (!check.has_command()) {
+ promise.fail("No check found in health check");
+ return;
+ }
+
+ const CommandInfo& command = check.command();
+
+ map<string, string> environment = os::environment();
+
+ foreach (const Environment::Variable& variable,
+ command.environment().variables()) {
+ environment[variable.name()] = variable.value();
+ }
+
+ // Launch the subprocess.
+ Option<Try<process::Subprocess>> external = None();
+
+ if (command.shell()) {
+ // Use the shell variant.
+ if (!command.has_value()) {
+ promise.fail("Shell command is not specified");
+ return;
+ }
+
+ VLOG(2) << "Launching health command '" << command.value() << "'";
+
+ external = process::subprocess(
+ command.value(),
+ process::Subprocess::PATH("/dev/null"),
+ process::Subprocess::FD(STDERR_FILENO),
+ process::Subprocess::FD(STDERR_FILENO),
+ process::NO_SETSID,
+ environment);
+ } else {
+ // Use the exec variant.
+ if (!command.has_value()) {
+ promise.fail("Executable path is not specified");
+ return;
+ }
+
+ vector<string> argv;
+ foreach (const string& arg, command.arguments()) {
+ argv.push_back(arg);
+ }
+
+ VLOG(2) << "Launching health command [" << command.value() << ", "
+ << strings::join(", ", argv) << "]";
+
+ external = process::subprocess(
+ command.value(),
+ argv,
+ process::Subprocess::PATH("/dev/null"),
+ process::Subprocess::FD(STDERR_FILENO),
+ process::Subprocess::FD(STDERR_FILENO),
+ process::NO_SETSID,
+ None(),
+ environment);
+ }
+
+ CHECK_SOME(external);
+
+ if (external.get().isError()) {
+ failure("Error creating subprocess for healthcheck: " +
+ external.get().error());
+ return;
+ }
+
+ pid_t commandPid = external.get().get().pid();
+
+ process::Future<Option<int>> status = external.get().get().status();
+ status.await(Seconds(check.timeout_seconds()));
+
+ if (!status.isReady()) {
+ string msg = "Command check failed with reason: ";
+ if (status.isFailed()) {
+ msg += "failed with error: " + status.failure();
+ } else if (status.isDiscarded()) {
+ msg += "status future discarded";
+ } else {
+ msg += "status still pending after timeout " +
+ stringify(Seconds(check.timeout_seconds()));
+ }
+
+ if (commandPid != -1) {
+ // Cleanup the external command process.
+ os::killtree(commandPid, SIGKILL);
+ VLOG(1) << "Kill health check command " << commandPid;
+ }
+
+ failure(msg);
+ return;
+ }
+
+ int statusCode = status.get().get();
+ if (statusCode != 0) {
+ string message = "Health command check " + WSTRINGIFY(statusCode);
+ failure(message);
+ } else {
+ success();
+ }
+ }
+
+ void reschedule()
+ {
+ VLOG(1) << "Rescheduling health check in "
+ << Seconds(check.interval_seconds());
+
+ delay(Seconds(check.interval_seconds()), self(), &Self::_healthCheck);
+ }
+
+ process::Promise<Nothing> promise;
+ HealthCheck check;
+ bool initializing;
+ UPID executor;
+ TaskID taskID;
+ uint32_t consecutiveFailures;
+ process::Time startTime;
+};
+
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __HEALTH_CHECKER_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/1556d9a3/src/health-check/main.cpp
----------------------------------------------------------------------
diff --git a/src/health-check/main.cpp b/src/health-check/main.cpp
index 4cc9dde..0b13926 100644
--- a/src/health-check/main.cpp
+++ b/src/health-check/main.cpp
@@ -23,258 +23,31 @@
#include <iostream>
#include <string>
-#include <vector>
#include <mesos/mesos.hpp>
-#include <process/defer.hpp>
-#include <process/delay.hpp>
#include <process/future.hpp>
-#include <process/io.hpp>
#include <process/pid.hpp>
#include <process/process.hpp>
#include <process/protobuf.hpp>
-#include <process/subprocess.hpp>
-#include <stout/duration.hpp>
#include <stout/flags.hpp>
#include <stout/json.hpp>
#include <stout/option.hpp>
-#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/protobuf.hpp>
-#include <stout/strings.hpp>
-#include <stout/os/killtree.hpp>
-
-#include "common/status_utils.hpp"
-
-#include "messages/messages.hpp"
+#include "health-check/health_checker.hpp"
using namespace mesos;
using std::cout;
using std::cerr;
using std::endl;
-using std::map;
using std::string;
-using std::vector;
using process::UPID;
-namespace mesos {
-namespace internal {
-
-using namespace process;
-
-class HealthCheckerProcess : public ProtobufProcess<HealthCheckerProcess>
-{
-public:
- HealthCheckerProcess(
- const HealthCheck& _check,
- const UPID& _executor,
- const TaskID& _taskID)
- : check(_check),
- initializing(true),
- executor(_executor),
- taskID(_taskID),
- consecutiveFailures(0) {}
-
- virtual ~HealthCheckerProcess() {}
-
- Future<Nothing> healthCheck()
- {
- VLOG(2) << "Health checks starting in "
- << Seconds(check.delay_seconds()) << ", grace period "
- << Seconds(check.grace_period_seconds());
-
- startTime = Clock::now();
-
- delay(Seconds(check.delay_seconds()), self(), &Self::_healthCheck);
- return promise.future();
- }
-
-private:
- void failure(const string& message)
- {
- if (check.grace_period_seconds() > 0 &&
- (Clock::now() - startTime).secs() <= check.grace_period_seconds()) {
- LOG(INFO) << "Ignoring failure as health check still in grace period";
- reschedule();
- return;
- }
-
- consecutiveFailures++;
- VLOG(1) << "#" << consecutiveFailures << " check failed: " << message;
-
- bool killTask = consecutiveFailures >= check.consecutive_failures();
-
- TaskHealthStatus taskHealthStatus;
- taskHealthStatus.set_healthy(false);
- taskHealthStatus.set_consecutive_failures(consecutiveFailures);
- taskHealthStatus.set_kill_task(killTask);
- taskHealthStatus.mutable_task_id()->CopyFrom(taskID);
- send(executor, taskHealthStatus);
-
- if (killTask) {
- // This is a hack to ensure the message is sent to the
- // executor before we exit the process. Without this,
- // we may exit before libprocess has sent the data over
- // the socket. See MESOS-4111.
- os::sleep(Seconds(1));
- promise.fail(message);
- } else {
- reschedule();
- }
- }
-
- void success()
- {
- VLOG(1) << "Check passed";
-
- // Send a healthy status update on the first success,
- // and on the first success following failure(s).
- if (initializing || consecutiveFailures > 0) {
- TaskHealthStatus taskHealthStatus;
- taskHealthStatus.set_healthy(true);
- taskHealthStatus.mutable_task_id()->CopyFrom(taskID);
- send(executor, taskHealthStatus);
- initializing = false;
- }
- consecutiveFailures = 0;
- reschedule();
- }
-
- void _healthCheck()
- {
- if (check.has_http()) {
- promise.fail("HTTP health check is not supported");
- return;
- }
-
- if (!check.has_command()) {
- promise.fail("No check found in health check");
- return;
- }
-
- const CommandInfo& command = check.command();
-
- map<string, string> environment = os::environment();
-
- foreach (const Environment::Variable& variable,
- command.environment().variables()) {
- environment[variable.name()] = variable.value();
- }
-
- // Launch the subprocess.
- Option<Try<Subprocess>> external = None();
-
- if (command.shell()) {
- // Use the shell variant.
- if (!command.has_value()) {
- promise.fail("Shell command is not specified");
- return;
- }
-
- VLOG(2) << "Launching health command '" << command.value() << "'";
-
- external = process::subprocess(
- command.value(),
- Subprocess::PATH("/dev/null"),
- Subprocess::FD(STDERR_FILENO),
- Subprocess::FD(STDERR_FILENO),
- process::NO_SETSID,
- environment);
- } else {
- // Use the exec variant.
- if (!command.has_value()) {
- promise.fail("Executable path is not specified");
- return;
- }
-
- vector<string> argv;
- foreach (const string& arg, command.arguments()) {
- argv.push_back(arg);
- }
-
- VLOG(2) << "Launching health command [" << command.value() << ", "
- << strings::join(", ", argv) << "]";
-
- external = process::subprocess(
- command.value(),
- argv,
- Subprocess::PATH("/dev/null"),
- Subprocess::FD(STDERR_FILENO),
- Subprocess::FD(STDERR_FILENO),
- process::NO_SETSID,
- None(),
- environment);
- }
-
- CHECK_SOME(external);
-
- if (external.get().isError()) {
- failure("Error creating subprocess for healthcheck: " +
- external.get().error());
- return;
- }
-
- pid_t commandPid = external.get().get().pid();
-
- Future<Option<int>> status = external.get().get().status();
- status.await(Seconds(check.timeout_seconds()));
-
- if (!status.isReady()) {
- string msg = "Command check failed with reason: ";
- if (status.isFailed()) {
- msg += "failed with error: " + status.failure();
- } else if (status.isDiscarded()) {
- msg += "status future discarded";
- } else {
- msg += "status still pending after timeout " +
- stringify(Seconds(check.timeout_seconds()));
- }
-
- if (commandPid != -1) {
- // Cleanup the external command process.
- os::killtree(commandPid, SIGKILL);
- VLOG(1) << "Kill health check command " << commandPid;
- }
-
- failure(msg);
- return;
- }
-
- int statusCode = status.get().get();
- if (statusCode != 0) {
- string message = "Health command check " + WSTRINGIFY(statusCode);
- failure(message);
- } else {
- success();
- }
- }
-
- void reschedule()
- {
- VLOG(1) << "Rescheduling health check in "
- << Seconds(check.interval_seconds());
-
- delay(Seconds(check.interval_seconds()), self(), &Self::_healthCheck);
- }
-
- Promise<Nothing> promise;
- HealthCheck check;
- bool initializing;
- UPID executor;
- TaskID taskID;
- uint32_t consecutiveFailures;
- process::Time startTime;
-};
-
-} // namespace internal {
-} // namespace mesos {
-
-
class Flags : public virtual flags::FlagsBase
{
public:
http://git-wip-us.apache.org/repos/asf/mesos/blob/1556d9a3/src/launcher/executor.cpp
----------------------------------------------------------------------
diff --git a/src/launcher/executor.cpp b/src/launcher/executor.cpp
index cb23501..6301025 100644
--- a/src/launcher/executor.cpp
+++ b/src/launcher/executor.cpp
@@ -79,6 +79,8 @@
#include "executor/v0_v1executor.hpp"
+#include "health-check/health_checker.hpp"
+
#include "launcher/executor.hpp"
#include "logging/logging.hpp"
@@ -109,6 +111,7 @@ using process::Timer;
using mesos::internal::devolve;
using mesos::internal::evolve;
+using mesos::internal::HealthChecker;
using mesos::internal::TaskHealthStatus;
using mesos::internal::protobuf::frameworkHasCapability;
@@ -146,7 +149,6 @@ public:
killedByHealthCheck(false),
terminated(false),
pid(-1),
- healthPid(-1),
shutdownGracePeriod(_shutdownGracePeriod),
frameworkInfo(None()),
taskId(None()),
@@ -423,7 +425,26 @@ protected:
cout << "Forked command at " << pid << endl;
if (task->has_health_check()) {
- launchHealthCheck(task.get());
+ Try<Owned<HealthChecker>> _checker = HealthChecker::create(
+ devolve(task->health_check()),
+ self(),
+ devolve(task->task_id()));
+
+ if (_checker.isError()) {
+ // TODO(gilbert): Consider ABORT and return a TASK_FAILED here.
+ cerr << "Failed to create health checker: "
+ << _checker.error() << endl;
+ } else {
+ checker = _checker.get();
+
+ checker->healthCheck()
+ .onAny([](const Future<Nothing>& future) {
+ // Only possible to be a failure.
+ if (future.isFailed()) {
+ cerr << "Healh check failed" << endl;
+ }
+ });
+ }
}
// Monitor this process.
@@ -581,17 +602,6 @@ private:
killGracePeriodStart = Clock::now();
killed = true;
}
-
- // Cleanup health check process.
- //
- // TODO(bmahler): Consider doing this after the task has been
- // reaped, since a framework may be interested in health
- // information while the task is being killed (consider a
- // task that takes 30 minutes to be cleanly killed).
- if (healthPid != -1) {
- os::killtree(healthPid, SIGKILL);
- healthPid = -1;
- }
}
void reaped(pid_t pid, const Future<Option<int> >& status_)
@@ -677,45 +687,6 @@ private:
}
}
- void launchHealthCheck(const TaskInfo& task)
- {
- CHECK(task.has_health_check());
-
- JSON::Object json = JSON::protobuf(task.health_check());
-
- // Launch the subprocess using 'exec' style so that quotes can
- // be properly handled.
- vector<string> argv(4);
- argv[0] = "mesos-health-check";
- argv[1] = "--executor=" + stringify(self());
- argv[2] = "--health_check_json=" + stringify(json);
- argv[3] = "--task_id=" + task.task_id().value();
-
- cout << "Launching health check process: "
- << path::join(healthCheckDir, "mesos-health-check")
- << " " << argv[1] << " " << argv[2] << " " << argv[3] << endl;
-
- Try<Subprocess> healthProcess =
- process::subprocess(
- path::join(healthCheckDir, "mesos-health-check"),
- argv,
- // Intentionally not sending STDIN to avoid health check
- // commands that expect STDIN input to block.
- Subprocess::PATH("/dev/null"),
- Subprocess::FD(STDOUT_FILENO),
- Subprocess::FD(STDERR_FILENO));
-
- if (healthProcess.isError()) {
- cerr << "Unable to launch health process: " << healthProcess.error();
- return;
- }
-
- healthPid = healthProcess.get().pid();
-
- cout << "Health check process launched at pid: "
- << stringify(healthPid) << endl;
- }
-
void update(
const TaskID& taskID,
const TaskState& state,
@@ -775,7 +746,6 @@ private:
#ifdef __WINDOWS__
HANDLE processHandle;
#endif
- pid_t healthPid;
Duration shutdownGracePeriod;
Option<KillPolicy> killPolicy;
Option<FrameworkInfo> frameworkInfo;
@@ -791,6 +761,7 @@ private:
Owned<MesosBase> mesos;
LinkedHashMap<UUID, Call::Update> updates; // Unacknowledged updates.
Option<TaskInfo> task; // Unacknowledged task.
+ Owned<HealthChecker> checker;
};
} // namespace internal {