aboutsummaryrefslogtreecommitdiffstats
path: root/configd
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2021-05-27 13:52:08 +0000
committerArne Juul <arnej@verizonmedia.com>2021-05-31 10:52:42 +0000
commitb741e5ffdfceb532c1166e778a072de8d4d1e6ea (patch)
treecb31e40859b6174a4bb4dba6f56db8e0392d263b /configd
parent781cb0770f50a5fd00bae0ecc0c5d323132ab166 (diff)
prepare for "check connectivity" api
* Cmd now has more generic "name" property and optional "portNumber" * add CmdType CHECK_CONNECTIVITY * add a simple one-shot PeerCheck utility * add CheckCompletionHandler that handles a Cmd with type CHECK_CONNECTIVITY * dummy in handleCmd for now
Diffstat (limited to 'configd')
-rw-r--r--configd/src/apps/sentinel/CMakeLists.txt3
-rw-r--r--configd/src/apps/sentinel/check-completion-handler.cpp31
-rw-r--r--configd/src/apps/sentinel/check-completion-handler.h27
-rw-r--r--configd/src/apps/sentinel/cmdq.h14
-rw-r--r--configd/src/apps/sentinel/manager.cpp10
-rw-r--r--configd/src/apps/sentinel/peer-check.cpp51
-rw-r--r--configd/src/apps/sentinel/peer-check.h37
-rw-r--r--configd/src/apps/sentinel/status-callback.cpp8
-rw-r--r--configd/src/apps/sentinel/status-callback.h13
9 files changed, 186 insertions, 8 deletions
diff --git a/configd/src/apps/sentinel/CMakeLists.txt b/configd/src/apps/sentinel/CMakeLists.txt
index f6b4c3a2184..d67a41f2a75 100644
--- a/configd/src/apps/sentinel/CMakeLists.txt
+++ b/configd/src/apps/sentinel/CMakeLists.txt
@@ -1,6 +1,7 @@
# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
vespa_add_executable(configd_config-sentinel_app
SOURCES
+ check-completion-handler.cpp
cmdq.cpp
config-owner.cpp
env.cpp
@@ -8,11 +9,13 @@ vespa_add_executable(configd_config-sentinel_app
manager.cpp
metrics.cpp
output-connection.cpp
+ peer-check.cpp
rpchooks.cpp
rpcserver.cpp
sentinel.cpp
service.cpp
state-api.cpp
+ status-callback.cpp
OUTPUT_NAME vespa-config-sentinel
INSTALL sbin
DEPENDS
diff --git a/configd/src/apps/sentinel/check-completion-handler.cpp b/configd/src/apps/sentinel/check-completion-handler.cpp
new file mode 100644
index 00000000000..f854a85d297
--- /dev/null
+++ b/configd/src/apps/sentinel/check-completion-handler.cpp
@@ -0,0 +1,31 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "check-completion-handler.h"
+#include <vespa/log/log.h>
+LOG_SETUP(".check-completion-handler");
+
+namespace config::sentinel {
+
+void CheckCompletionHandler::create(Cmd::UP request, FRT_Supervisor &orb) {
+ LOG_ASSERT(request->type() == Cmd::CHECK_CONNECTIVITY);
+ // will delete itself on completion:
+ new CheckCompletionHandler(std::move(request), orb);
+}
+
+CheckCompletionHandler::CheckCompletionHandler(Cmd::UP request, FRT_Supervisor &orb)
+ : _parentRequest(std::move(request))
+{
+ const std::string & host = _parentRequest->name();
+ int port = _parentRequest->portNumber();
+ _peerCheck = std::make_unique<PeerCheck>(*this, host, port, orb);
+
+}
+
+CheckCompletionHandler::~CheckCompletionHandler() = default;
+
+void CheckCompletionHandler::returnStatus(bool ok) {
+ _parentRequest->retValue(ok ? "ok" : "bad");
+ delete this;
+}
+
+}
diff --git a/configd/src/apps/sentinel/check-completion-handler.h b/configd/src/apps/sentinel/check-completion-handler.h
new file mode 100644
index 00000000000..ae43799dd54
--- /dev/null
+++ b/configd/src/apps/sentinel/check-completion-handler.h
@@ -0,0 +1,27 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "status-callback.h"
+#include "peer-check.h"
+#include "cmdq.h"
+
+namespace config::sentinel {
+
+/**
+ * Handles a checkConnectivity request by making an outgoing
+ * ping request. When the ping finishes, fills an answer
+ * into the parent request and deletes itself.
+ **/
+class CheckCompletionHandler : public StatusCallback {
+public:
+ static void create(Cmd::UP request, FRT_Supervisor &orb);
+ virtual ~CheckCompletionHandler();
+ void returnStatus(bool ok) override;
+private:
+ CheckCompletionHandler(Cmd::UP request, FRT_Supervisor &orb);
+ Cmd::UP _parentRequest;
+ std::unique_ptr<PeerCheck> _peerCheck;
+};
+
+}
diff --git a/configd/src/apps/sentinel/cmdq.h b/configd/src/apps/sentinel/cmdq.h
index 105d5f29b60..38c95967d70 100644
--- a/configd/src/apps/sentinel/cmdq.h
+++ b/configd/src/apps/sentinel/cmdq.h
@@ -5,6 +5,7 @@
#include <memory>
#include <mutex>
#include <vector>
+#include <string>
class FRT_RPCRequest;
@@ -13,14 +14,16 @@ namespace config::sentinel {
class Cmd {
public:
using UP = std::unique_ptr<Cmd>;
- enum CmdType { LIST, RESTART, START, STOP };
+ enum CmdType { LIST, RESTART, START, STOP, CHECK_CONNECTIVITY };
- Cmd(FRT_RPCRequest *req, CmdType cmdType, const char *service = "")
- : _req(req), _cmdType(cmdType), _serviceName(service)
+ Cmd(FRT_RPCRequest *req, CmdType cmdType, std::string name = "", int portnum = 0)
+ : _req(req), _cmdType(cmdType), _name(name), _port(portnum)
{}
CmdType type() const { return _cmdType; }
- const char *serviceName() const { return _serviceName; }
+ // the service name or host name:
+ const std::string & name() const { return _name; }
+ int portNumber() const { return _port; }
void retError(const char *errorString) const;
void retValue(const char *valueString) const;
@@ -29,7 +32,8 @@ public:
private:
FRT_RPCRequest *_req;
CmdType _cmdType;
- const char *_serviceName;
+ std::string _name;
+ int _port;
};
class CommandQueue
diff --git a/configd/src/apps/sentinel/manager.cpp b/configd/src/apps/sentinel/manager.cpp
index 80dd2a3fda8..6f8bf69cb83 100644
--- a/configd/src/apps/sentinel/manager.cpp
+++ b/configd/src/apps/sentinel/manager.cpp
@@ -271,7 +271,7 @@ Manager::handleCmd(const Cmd& cmd)
break;
case Cmd::RESTART:
{
- Service *service = serviceByName(cmd.serviceName());
+ Service *service = serviceByName(cmd.name());
if (service == nullptr) {
cmd.retError("Cannot find named service");
return;
@@ -287,7 +287,7 @@ Manager::handleCmd(const Cmd& cmd)
break;
case Cmd::START:
{
- Service *service = serviceByName(cmd.serviceName());
+ Service *service = serviceByName(cmd.name());
if (service == nullptr) {
cmd.retError("Cannot find named service");
return;
@@ -301,7 +301,7 @@ Manager::handleCmd(const Cmd& cmd)
break;
case Cmd::STOP:
{
- Service *service = serviceByName(cmd.serviceName());
+ Service *service = serviceByName(cmd.name());
if (service == nullptr) {
cmd.retError("Cannot find named service");
return;
@@ -312,6 +312,10 @@ Manager::handleCmd(const Cmd& cmd)
}
}
break;
+ case Cmd::CHECK_CONNECTIVITY:
+ // XXX placeholder:
+ cmd.retValue("unknown");
+ break;
}
}
diff --git a/configd/src/apps/sentinel/peer-check.cpp b/configd/src/apps/sentinel/peer-check.cpp
new file mode 100644
index 00000000000..6aef1443ef2
--- /dev/null
+++ b/configd/src/apps/sentinel/peer-check.cpp
@@ -0,0 +1,51 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "peer-check.h"
+#include <vespa/vespalib/util/stringfmt.h>
+#include <vespa/log/log.h>
+
+LOG_SETUP(".peer-check");
+
+using vespalib::make_string_short::fmt;
+
+namespace config::sentinel {
+
+PeerCheck::PeerCheck(StatusCallback &callback, const std::string &host, int port, FRT_Supervisor &orb)
+ : _callback(callback),
+ _hostname(host),
+ _portnum(port),
+ _target(nullptr),
+ _req(nullptr)
+{
+ auto spec = fmt("tcp/%s:%d", _hostname.c_str(), _portnum);
+ _target = orb.GetTarget(spec.c_str());
+ _req = orb.AllocRPCRequest();
+ _req->SetMethodName("frt.rpc.ping");
+ _target->InvokeAsync(_req, 0.500, this);
+}
+
+PeerCheck::~PeerCheck() {
+ if (_req != nullptr) {
+ _req->Abort();
+ }
+}
+
+void PeerCheck::RequestDone(FRT_RPCRequest *req) {
+ LOG_ASSERT(req == _req);
+ bool statusOk = false;
+ if (req->IsError()) {
+ LOG(warning, "error on ping to %s [port %d]: %s (%d)", _hostname.c_str(), _portnum,
+ req->GetErrorMessage(), req->GetErrorCode());
+ } else {
+ LOG(info, "OK ping to %s [port %d]", _hostname.c_str(), _portnum);
+ statusOk = true;
+ }
+ _req->SubRef();
+ _req = nullptr;
+ _target->SubRef();
+ _target = nullptr;
+ // Note: will delete this object, so must be called as final step:
+ _callback.returnStatus(statusOk);
+}
+
+}
diff --git a/configd/src/apps/sentinel/peer-check.h b/configd/src/apps/sentinel/peer-check.h
new file mode 100644
index 00000000000..658375a8d7b
--- /dev/null
+++ b/configd/src/apps/sentinel/peer-check.h
@@ -0,0 +1,37 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include "status-callback.h"
+#include <string>
+#include <vespa/fnet/task.h>
+#include <vespa/fnet/frt/invoker.h>
+#include <vespa/fnet/frt/rpcrequest.h>
+#include <vespa/fnet/frt/supervisor.h>
+#include <vespa/fnet/frt/target.h>
+
+namespace config::sentinel {
+
+class PeerCheck : public FRT_IRequestWait
+{
+public:
+ PeerCheck(StatusCallback &callback, const std::string &host, int portnum, FRT_Supervisor &orb);
+ ~PeerCheck();
+
+ PeerCheck(const PeerCheck &) = delete;
+ PeerCheck(PeerCheck &&) = delete;
+ PeerCheck& operator= (const PeerCheck &) = delete;
+ PeerCheck& operator= (PeerCheck &&) = delete;
+
+ /** from FRT_IRequestWait **/
+ void RequestDone(FRT_RPCRequest *req) override;
+
+private:
+ StatusCallback &_callback;
+ std::string _hostname;
+ int _portnum;
+ FRT_Target *_target;
+ FRT_RPCRequest *_req;
+};
+
+}
diff --git a/configd/src/apps/sentinel/status-callback.cpp b/configd/src/apps/sentinel/status-callback.cpp
new file mode 100644
index 00000000000..9bd820c9f39
--- /dev/null
+++ b/configd/src/apps/sentinel/status-callback.cpp
@@ -0,0 +1,8 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "status-callback.h"
+namespace config::sentinel {
+
+StatusCallback::~StatusCallback() = default;
+
+}
diff --git a/configd/src/apps/sentinel/status-callback.h b/configd/src/apps/sentinel/status-callback.h
new file mode 100644
index 00000000000..53a3185623b
--- /dev/null
+++ b/configd/src/apps/sentinel/status-callback.h
@@ -0,0 +1,13 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+namespace config::sentinel {
+
+/** very simple callback API with "ok" or "not ok" status only */
+struct StatusCallback {
+ virtual void returnStatus(bool ok) = 0;
+ virtual ~StatusCallback();
+};
+
+}