summaryrefslogtreecommitdiffstats
path: root/configd
diff options
context:
space:
mode:
authorArne H Juul <arnej27959@users.noreply.github.com>2021-06-01 12:59:05 +0200
committerGitHub <noreply@github.com>2021-06-01 12:59:05 +0200
commita2c9fe21f092d7992df4fa8657a2f5d97b574413 (patch)
tree6d0d9b84678072d5c61f6f2120a84f6cfb05d6d1 /configd
parent93cc6c475cbd34fe2671ba1e5ef06401e6439d8f (diff)
parentf93f5c60a753bf177daa1944cc5fef2afec0f227 (diff)
Merge pull request #18036 from vespa-engine/arnej/prepare-for-more-generic-rpc
Arnej/prepare for more generic rpc
Diffstat (limited to 'configd')
-rw-r--r--configd/src/apps/sentinel/CMakeLists.txt3
-rw-r--r--configd/src/apps/sentinel/check-completion-handler.cpp20
-rw-r--r--configd/src/apps/sentinel/check-completion-handler.h24
-rw-r--r--configd/src/apps/sentinel/env.cpp5
-rw-r--r--configd/src/apps/sentinel/env.h2
-rw-r--r--configd/src/apps/sentinel/peer-check.cpp50
-rw-r--r--configd/src/apps/sentinel/peer-check.h37
-rw-r--r--configd/src/apps/sentinel/rpchooks.cpp28
-rw-r--r--configd/src/apps/sentinel/rpchooks.h9
-rw-r--r--configd/src/apps/sentinel/rpcserver.cpp3
-rw-r--r--configd/src/apps/sentinel/status-callback.cpp6
-rw-r--r--configd/src/apps/sentinel/status-callback.h14
12 files changed, 194 insertions, 7 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..3ccda17e617
--- /dev/null
+++ b/configd/src/apps/sentinel/check-completion-handler.cpp
@@ -0,0 +1,20 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "check-completion-handler.h"
+
+namespace config::sentinel {
+
+CheckCompletionHandler::CheckCompletionHandler(FRT_RPCRequest *parent)
+ : _parentRequest(parent)
+{
+}
+
+CheckCompletionHandler::~CheckCompletionHandler() = default;
+
+void CheckCompletionHandler::returnStatus(bool ok) {
+ FRT_Values *dst = _parentRequest->GetReturn();
+ dst->AddString(ok ? "ok" : "bad");
+ _parentRequest->Return();
+}
+
+}
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..008e456f6d7
--- /dev/null
+++ b/configd/src/apps/sentinel/check-completion-handler.h
@@ -0,0 +1,24 @@
+// 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"
+
+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 send the answer back.
+ **/
+class CheckCompletionHandler : public StatusCallback {
+private:
+ FRT_RPCRequest *_parentRequest;
+public:
+ CheckCompletionHandler(FRT_RPCRequest *parentRequest);
+ virtual ~CheckCompletionHandler();
+ void returnStatus(bool ok) override;
+};
+
+}
diff --git a/configd/src/apps/sentinel/env.cpp b/configd/src/apps/sentinel/env.cpp
index 11ba20a18d5..745fa8cef1f 100644
--- a/configd/src/apps/sentinel/env.cpp
+++ b/configd/src/apps/sentinel/env.cpp
@@ -1,6 +1,7 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "env.h"
+#include "check-completion-handler.h"
#include <vespa/log/log.h>
#include <vespa/config/common/exceptions.h>
#include <vespa/vespalib/util/exceptions.h>
@@ -75,4 +76,8 @@ void Env::notifyConfigUpdated() {
}
+void Env::handleCmd(Cmd::UP cmd) {
+ cmd->retError("still booting, not ready for all RPC commands");
+}
+
}
diff --git a/configd/src/apps/sentinel/env.h b/configd/src/apps/sentinel/env.h
index da04a328c41..0213fd09460 100644
--- a/configd/src/apps/sentinel/env.h
+++ b/configd/src/apps/sentinel/env.h
@@ -30,7 +30,7 @@ public:
void statePort(int portnum);
void notifyConfigUpdated();
-
+ void handleCmd(Cmd::UP cmd);
private:
ConfigOwner _cfgOwner;
CommandQueue _rpcCommandQueue;
diff --git a/configd/src/apps/sentinel/peer-check.cpp b/configd/src/apps/sentinel/peer-check.cpp
new file mode 100644
index 00000000000..024f928c994
--- /dev/null
+++ b/configd/src/apps/sentinel/peer-check.cpp
@@ -0,0 +1,50 @@
+// 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() {
+ LOG_ASSERT(_req == nullptr);
+ LOG_ASSERT(_target == nullptr);
+}
+
+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/rpchooks.cpp b/configd/src/apps/sentinel/rpchooks.cpp
index aef58b8a1dc..d364e74154c 100644
--- a/configd/src/apps/sentinel/rpchooks.cpp
+++ b/configd/src/apps/sentinel/rpchooks.cpp
@@ -2,6 +2,8 @@
#include "rpchooks.h"
#include "cmdq.h"
+#include "check-completion-handler.h"
+#include "peer-check.h"
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/fnet/frt/rpcrequest.h>
@@ -10,6 +12,13 @@ LOG_SETUP(".rpchooks");
namespace config::sentinel {
+RPCHooks::RPCHooks(CommandQueue &commands, FRT_Supervisor &supervisor)
+ : _commands(commands),
+ _orb(supervisor)
+{
+ initRPC(&_orb);
+}
+
RPCHooks::~RPCHooks() = default;
@@ -36,6 +45,13 @@ RPCHooks::initRPC(FRT_Supervisor *supervisor)
FRT_METHOD(RPCHooks::rpc_startService), this);
rb.MethodDesc("start a service");
//-------------------------------------------------------------------------
+ rb.DefineMethod("sentinel.check.connectivity", "si", "s",
+ FRT_METHOD(RPCHooks::rpc_checkConnectivity), this);
+ rb.MethodDesc("check connectivity for peer sentinel");
+ rb.ParamDesc("name", "Hostname of peer sentinel");
+ rb.ParamDesc("port", "Port number of peer sentinel");
+ rb.ReturnDesc("status", "Status (ok, bad, or unknown) for peer");
+ //-------------------------------------------------------------------------
}
void
@@ -76,4 +92,16 @@ RPCHooks::rpc_startService(FRT_RPCRequest *req)
_commands.enqueue(std::make_unique<Cmd>(req, Cmd::START, srvNM));
}
+void
+RPCHooks::rpc_checkConnectivity(FRT_RPCRequest *req)
+{
+ FRT_Values &args = *req->GetParams();
+ const char *hostname = args[0]._string._str;
+ uint32_t portnum = args[1]._intval32;
+ LOG(debug, "got checkConnectivity %s [port %d]", hostname, portnum);
+ req->Detach();
+ auto & completionHandler = req->getStash().create<CheckCompletionHandler>(req);
+ req->getStash().create<PeerCheck>(completionHandler, hostname, portnum, _orb);
+}
+
} // namespace slobrok
diff --git a/configd/src/apps/sentinel/rpchooks.h b/configd/src/apps/sentinel/rpchooks.h
index 05070830491..67f5804dcf7 100644
--- a/configd/src/apps/sentinel/rpchooks.h
+++ b/configd/src/apps/sentinel/rpchooks.h
@@ -24,17 +24,18 @@ class RPCHooks : public FRT_Invokable
{
private:
CommandQueue &_commands;
-
+ FRT_Supervisor &_orb;
public:
- RPCHooks(CommandQueue &commands) : _commands(commands) {}
+ RPCHooks(CommandQueue &commands, FRT_Supervisor &supervisor);
~RPCHooks() override;
-
- void initRPC(FRT_Supervisor *supervisor);
private:
+ void initRPC(FRT_Supervisor *supervisor);
+
void rpc_listServices(FRT_RPCRequest *req);
void rpc_restartService(FRT_RPCRequest *req);
void rpc_stopService(FRT_RPCRequest *req);
void rpc_startService(FRT_RPCRequest *req);
+ void rpc_checkConnectivity(FRT_RPCRequest *req);
};
} // namespace config::sentinel
diff --git a/configd/src/apps/sentinel/rpcserver.cpp b/configd/src/apps/sentinel/rpcserver.cpp
index a49cba50e4d..80c3c81c826 100644
--- a/configd/src/apps/sentinel/rpcserver.cpp
+++ b/configd/src/apps/sentinel/rpcserver.cpp
@@ -9,10 +9,9 @@ namespace config::sentinel {
RpcServer::RpcServer(int portNumber, CommandQueue &cmdQ)
: _server(),
- _rpcHooks(cmdQ),
+ _rpcHooks(cmdQ, _server.supervisor()),
_port(portNumber)
{
- _rpcHooks.initRPC(&_server.supervisor());
if (_server.supervisor().Listen(portNumber)) {
LOG(config, "listening on port %d", portNumber);
} else {
diff --git a/configd/src/apps/sentinel/status-callback.cpp b/configd/src/apps/sentinel/status-callback.cpp
new file mode 100644
index 00000000000..0bf11050b8e
--- /dev/null
+++ b/configd/src/apps/sentinel/status-callback.cpp
@@ -0,0 +1,6 @@
+// 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 {
+
+}
diff --git a/configd/src/apps/sentinel/status-callback.h b/configd/src/apps/sentinel/status-callback.h
new file mode 100644
index 00000000000..54100277fdc
--- /dev/null
+++ b/configd/src/apps/sentinel/status-callback.h
@@ -0,0 +1,14 @@
+// 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;
+protected:
+ ~StatusCallback() = default;
+};
+
+}