You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bb...@apache.org on 2019/08/01 09:09:08 UTC

[mesos] 03/06: Stored last time a drain request was sent in the master.

This is an automated email from the ASF dual-hosted git repository.

bbannier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 7a41e50a38d3c20680850adbbe9198be17aa5bb6
Author: Benjamin Bannier <bb...@apache.org>
AuthorDate: Wed Jul 31 13:46:28 2019 +0200

    Stored last time a drain request was sent in the master.
    
    This information can be used to calculate an approximate time when
    draining an agent would be finished, e.g., by comparing
    `DrainConfig.max_grace_period` and the field
    `estimated_drain_start_time` added here, both obtained from the master
    API simultaneously. This information is necessarily approximate as the
    agent might e.g., fail over before it has finished draining which would
    reset the timeout; for that specific case the master would send the
    drain request again so after some time the value calculated from the
    master API would be in line with the expected true value.
    
    Review: https://reviews.apache.org/r/71182/
---
 include/mesos/master/master.proto    |  1 +
 include/mesos/v1/master/master.proto |  1 +
 src/common/protobuf_utils.cpp        |  5 +++++
 src/master/http.cpp                  |  4 ++++
 src/master/master.hpp                |  4 ++++
 src/master/readonly_handler.cpp      |  6 ++++++
 src/tests/api_tests.cpp              | 13 +++++++++++++
 7 files changed, 34 insertions(+)

diff --git a/include/mesos/master/master.proto b/include/mesos/master/master.proto
index 07bf4e7..153be68 100644
--- a/include/mesos/master/master.proto
+++ b/include/mesos/master/master.proto
@@ -470,6 +470,7 @@ message Response {
       repeated ResourceProvider resource_providers = 11;
 
       optional DrainInfo drain_info = 13;
+      optional TimeInfo estimated_drain_start_time = 14;
     }
 
     // Registered agents.
diff --git a/include/mesos/v1/master/master.proto b/include/mesos/v1/master/master.proto
index 9bcef2f..4906b94 100644
--- a/include/mesos/v1/master/master.proto
+++ b/include/mesos/v1/master/master.proto
@@ -471,6 +471,7 @@ message Response {
       repeated ResourceProvider resource_providers = 11;
 
       optional DrainInfo drain_info = 13;
+      optional TimeInfo estimated_drain_start_time = 14;
     }
 
     // Registered agents.
diff --git a/src/common/protobuf_utils.cpp b/src/common/protobuf_utils.cpp
index 7778e7f..64777c0 100644
--- a/src/common/protobuf_utils.cpp
+++ b/src/common/protobuf_utils.cpp
@@ -1568,6 +1568,11 @@ mesos::master::Response::GetAgents::Agent createAgentResponse(
 
   if (drainInfo.isSome()) {
     agent.mutable_drain_info()->CopyFrom(drainInfo.get());
+
+    if (slave.estimatedDrainStartTime.isSome()) {
+      agent.mutable_estimated_drain_start_time()->set_nanoseconds(
+          Seconds(slave.estimatedDrainStartTime->secs()).ns());
+    }
   }
 
   return agent;
diff --git a/src/master/http.cpp b/src/master/http.cpp
index 765d505..684a0f7 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -3933,6 +3933,8 @@ Future<Response> Master::Http::_drainAgent(
             message.mutable_config()->CopyFrom(drainConfig);
             master->send(slave->pid, message);
 
+            slave->estimatedDrainStartTime = Clock::now();
+
             // Check if the agent is already drained and transition it
             // appropriately if so.
             master->checkAndTransitionDrainingAgent(slave);
@@ -4103,6 +4105,8 @@ Future<Response> Master::Http::_reactivateAgent(
         master->reactivate(slave);
       }
 
+      slave->estimatedDrainStartTime = None();
+
       return OK();
     }));
 }
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 8bdbac9..783e4a3 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -315,6 +315,10 @@ Slave(Master* const _master,
 
   SlaveObserver* observer;
 
+  // Time when this agent was last asked to drain. This field
+  // is empty if the agent is not currently draining or drained.
+  Option<process::Time> estimatedDrainStartTime;
+
   struct ResourceProvider {
     ResourceProviderInfo info;
     Resources totalResources;
diff --git a/src/master/readonly_handler.cpp b/src/master/readonly_handler.cpp
index a893115..b226ae1 100644
--- a/src/master/readonly_handler.cpp
+++ b/src/master/readonly_handler.cpp
@@ -336,6 +336,12 @@ void SlaveWriter::operator()(JSON::ObjectWriter* writer) const
 
   if (drainInfo_.isSome()) {
     writer->field("drain_info", JSON::Protobuf(drainInfo_.get()));
+
+    if (slave_.estimatedDrainStartTime.isSome()) {
+      writer->field(
+          "estimated_drain_start_time_seconds",
+          slave_.estimatedDrainStartTime->secs());
+    }
   }
 }
 
diff --git a/src/tests/api_tests.cpp b/src/tests/api_tests.cpp
index 641eb15..0ce2d25 100644
--- a/src/tests/api_tests.cpp
+++ b/src/tests/api_tests.cpp
@@ -5628,6 +5628,7 @@ TEST_P(MasterAPITest, DrainAgent)
     EXPECT_EQ(agent.deactivated(), true);
 
     EXPECT_EQ(agent.drain_info(), drainInfo);
+    EXPECT_LT(0, agent.estimated_drain_start_time().nanoseconds());
   }
 
   // Ensure that the agent's drain info is reflected in the master's
@@ -5649,6 +5650,12 @@ TEST_P(MasterAPITest, DrainAgent)
         "slaves[0].drain_info");
 
     ASSERT_SOME_EQ(JSON::protobuf(drainInfo), stateDrainInfo);
+
+    Result<JSON::Number> stateDrainStartTime = parse->find<JSON::Number>(
+        "slaves[0].estimated_drain_start_time_seconds");
+
+    ASSERT_SOME(stateDrainStartTime);
+    EXPECT_LT(0, stateDrainStartTime->as<int>());
   }
 
   // Ensure that the agent's drain info is reflected in the master's
@@ -5670,6 +5677,12 @@ TEST_P(MasterAPITest, DrainAgent)
         "slaves[0].drain_info");
 
     ASSERT_SOME_EQ(JSON::protobuf(drainInfo), stateDrainInfo);
+
+    Result<JSON::Number> stateDrainStartTime =
+      parse->find<JSON::Number>("slaves[0].estimated_drain_start_time_seconds");
+
+    ASSERT_SOME(stateDrainStartTime);
+    EXPECT_LT(0, stateDrainStartTime->as<int>());
   }
 }