diff options
author | Arne H Juul <arnej27959@users.noreply.github.com> | 2021-06-01 12:59:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-01 12:59:05 +0200 |
commit | a2c9fe21f092d7992df4fa8657a2f5d97b574413 (patch) | |
tree | 6d0d9b84678072d5c61f6f2120a84f6cfb05d6d1 /configd | |
parent | 93cc6c475cbd34fe2671ba1e5ef06401e6439d8f (diff) | |
parent | f93f5c60a753bf177daa1944cc5fef2afec0f227 (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.txt | 3 | ||||
-rw-r--r-- | configd/src/apps/sentinel/check-completion-handler.cpp | 20 | ||||
-rw-r--r-- | configd/src/apps/sentinel/check-completion-handler.h | 24 | ||||
-rw-r--r-- | configd/src/apps/sentinel/env.cpp | 5 | ||||
-rw-r--r-- | configd/src/apps/sentinel/env.h | 2 | ||||
-rw-r--r-- | configd/src/apps/sentinel/peer-check.cpp | 50 | ||||
-rw-r--r-- | configd/src/apps/sentinel/peer-check.h | 37 | ||||
-rw-r--r-- | configd/src/apps/sentinel/rpchooks.cpp | 28 | ||||
-rw-r--r-- | configd/src/apps/sentinel/rpchooks.h | 9 | ||||
-rw-r--r-- | configd/src/apps/sentinel/rpcserver.cpp | 3 | ||||
-rw-r--r-- | configd/src/apps/sentinel/status-callback.cpp | 6 | ||||
-rw-r--r-- | configd/src/apps/sentinel/status-callback.h | 14 |
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; +}; + +} |