Skip to content

Commit

Permalink
feat: support ping method
Browse files Browse the repository at this point in the history
Signed-off-by: ik <[email protected]>
  • Loading branch information
hiiiik committed Jun 21, 2024
1 parent 3c3d0fc commit 17b9dd3
Show file tree
Hide file tree
Showing 21 changed files with 691 additions and 6 deletions.
41 changes: 41 additions & 0 deletions include/opengemini/Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <memory>

#include "opengemini/ClientConfig.hpp"
#include "opengemini/CompletionToken.hpp"

namespace opengemini {

Expand Down Expand Up @@ -57,6 +58,46 @@ class Client {
Client(Client&& client) noexcept;
Client& operator=(Client&& client) noexcept;

///
/// \~English
/// @brief Check the status of the database.
/// @details Check conectivity with specified database through sending ping

Check warning on line 64 in include/opengemini/Client.hpp

View workflow job for this annotation

GitHub Actions / typo check

"conectivity" should be "connectivity".
/// request, and return the version of the server.
/// @param index Index of database.
/// @param token The completion token which will be invoked when the task
/// complete. Default to @ref token::sync if this parameter is not
/// specified. If passing function object as token, the function signature
/// must be:
/// @code
/// void (
/// // Result of operation, it means success if the value is nullptr,
/// // otherwise, contains an exception.
/// std::exception_ptr error,
/// // On success, the version of OpenGemini server.
/// std::string verison

Check warning on line 77 in include/opengemini/Client.hpp

View workflow job for this annotation

GitHub Actions / typo check

"verison" should be "version".
/// )
/// @endcode
///
/// \~Chinese
/// @brief 检查数据库的连接状态。
/// @details
/// 发送Ping请求以测试指定数据库的连接是否正常,将返回服务端的版本号。
/// @param index 数据库集群索引。
/// @param token 任务完成令牌,将在任务完成后被调用。
/// 若没有指定该参数,则使用默认值:@ref token::sync 。
/// 若传递函数对象作为完成令牌,则其签名必须满足:
/// @code
/// void (
/// // 执行结果,仅当值为nullptr时代表成功,否则将承载相关的异常。
/// std::exception_ptr error,
/// // 当操作成功时,承载服务端的版本号。
/// std::string verison

Check warning on line 94 in include/opengemini/Client.hpp

View workflow job for this annotation

GitHub Actions / typo check

"verison" should be "version".
/// )
/// @endcode
///
template<typename COMPLETION_TOKEN = token::Sync>
[[nodiscard]] auto Ping(std::size_t index, COMPLETION_TOKEN&& token = {});

private:
Client(const Client&) = delete;
Client& operator=(const Client&) = delete;
Expand Down
90 changes: 90 additions & 0 deletions include/opengemini/CompletionToken.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// Copyright 2024 Huawei Cloud Computing Technologies Co., Ltd.
//
// Licensed 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.
//

/// @file CompletionToken.hpp
#ifndef OPENGEMINI_COMPLETIONTOKEN_HPP
#define OPENGEMINI_COMPLETIONTOKEN_HPP

#include <boost/asio/deferred.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <boost/asio/use_future.hpp>

namespace opengemini::token {

class Sync { };

///
/// \~English
/// @brief A completion token that causes an operation blocking until the
/// task completes or an exception is thrown.
///
/// \~Chinese
/// @brief 该完成令牌使操作阻塞直到任务完成或抛出异常。
///
constexpr Sync sync{};

///
/// \~English
/// @brief A completion token that causes an operation to return a future.
///
/// \~Chinese
/// @brief 该完成令牌使操作返回future对象。
///
constexpr auto future = boost::asio::use_future;

///
/// \~English
/// @brief A completion token that indicate an operation is detached, that is,
/// there is no handler waiting for ther operation's result.

Check warning on line 52 in include/opengemini/CompletionToken.hpp

View workflow job for this annotation

GitHub Actions / typo check

"ther" should be "there" or "their" or "the" or "other".
///
/// \~Chinese
/// @brief
/// 该完成令牌指示操作应当独立运行,既不感知也不处理任务的结果。
///
constexpr auto detached = boost::asio::detached;

///
/// \~English
/// @brief A completion token that specify an operation should return a function
/// object to lazily launch the operation, instead of starting the asynchronous
/// task immediately.
///
/// \~Chinese
/// @brief
/// 该完成令牌指示操作不要立即启动异步任务,而是返回一个函数对象用于懒启动。
///
constexpr auto deferred = boost::asio::deferred;

#if __cplusplus >= 202002L

///
/// \~English
/// @brief A completion token that represent the currently executing coroutine.
///
/// \~Chinese
/// @brief
/// 该完成令牌用于表示当前正在执行的协程。
///
constexpr auto coro = boost::asio::use_awaitable;

#endif // (__cplusplus < 202002L)

} // namespace opengemini::token

#include "opengemini/impl/CompletionToken.tpp"

#endif // !OPENGEMINI_COMPLETIONTOKEN_HPP
1 change: 1 addition & 0 deletions include/opengemini/Error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ enum class LogicErrors {

enum class ServerErrors {
NoAvailableServer = 1,
UnexceptedStatusCode,

Check warning on line 137 in include/opengemini/Error.hpp

View workflow job for this annotation

GitHub Actions / typo check

"Unexcepted" should be "Unexpected".
};

enum class RuntimeErrors {
Expand Down
6 changes: 6 additions & 0 deletions include/opengemini/impl/Client.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@ inline Client& Client::operator=(Client&& client) noexcept
return *this;
}

template<typename COMPLETION_TOKEN>
auto Client::Ping(std::size_t index, COMPLETION_TOKEN&& token)
{
return impl_->Ping(index, std::forward<COMPLETION_TOKEN>(token));
}

} // namespace opengemini
61 changes: 60 additions & 1 deletion include/opengemini/impl/ClientImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,70 @@

#include "opengemini/impl/ClientImpl.hpp"

#include <fmt/format.h>

#include "opengemini/Exception.hpp"
#include "opengemini/impl/http/HttpClient.hpp"
#ifdef OPENGEMINI_ENABLE_SSL_SUPPORT
# include "opengemini/impl/http/HttpsClient.hpp"
#endif // OPENGEMINI_ENABLE_SSL_SUPPORT
#include "opengemini/impl/util/Base64.hpp"
#include "opengemini/impl/util/Preprocessor.hpp"

namespace opengemini::impl {

OPENGEMINI_INLINE_SPECIFIER
ClientImpl::ClientImpl(const ClientConfig& config) { }
ClientImpl::ClientImpl(const ClientConfig& config) :
ctx_(config.concurrencyHint),
http_(ConstructHttpClient(config)),
lb_(lb::LoadBalancer::Construct(ctx_(), config.addresses, http_))
{
lb_->StartHealthCheck();
}

OPENGEMINI_INLINE_SPECIFIER
ClientImpl::~ClientImpl()
{
lb_->StopHealthCheck();
ctx_.Shutdown();
}

OPENGEMINI_INLINE_SPECIFIER
std::shared_ptr<http::IHttpClient>
ClientImpl::ConstructHttpClient(const ClientConfig& config)
{
std::shared_ptr<http::IHttpClient> http;
#ifdef OPENGEMINI_ENABLE_SSL_SUPPORT
if (config.tlsEnabled) {
http = std::make_shared<http::HttpsClient>(
ctx_(),
config.connectTimeout,
config.timeout,
config.tlsConfig.value_or(TLSConfig{}));
}
else
#endif // OPENGEMINI_ENABLE_SSL_SUPPORT
{
http = std::make_shared<http::HttpClient>(ctx_(),
config.connectTimeout,
config.timeout);
}

if (auto& auth = config.authConfig; auth.has_value()) {
auto val = std::get_if<AuthCredential>(&auth.value());
if (!val) {
throw Exception(errc::LogicErrors::NotImplemented,
"Only support authorization credential");
}

auto cred = fmt::format("{}:{}", val->username, val->password);
http->DefaultHeaders()["Authorization"] =
fmt::format("Basic {}", util::Base64Encode(cred));
}

return http;
};

} // namespace opengemini::impl

#include "opengemini/impl/cli/Ping.cpp"
45 changes: 43 additions & 2 deletions include/opengemini/impl/ClientImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,61 @@
#ifndef OPENGEMINI_IMPL_CLIENTIMPL_HPP
#define OPENGEMINI_IMPL_CLIENTIMPL_HPP

#include <memory>
#include <type_traits>

#include "opengemini/ClientConfig.hpp"
#include "opengemini/impl/comm/Context.hpp"
#include "opengemini/impl/http/IHttpClient.hpp"
#include "opengemini/impl/lb/LoadBalancer.hpp"
#include "opengemini/impl/util/TypeTraits.hpp"

namespace opengemini::impl {

class ClientImpl {
public:
explicit ClientImpl(const ClientConfig& config);
~ClientImpl() = default;
~ClientImpl();

template<typename COMPLETION_TOKEN>
auto Ping(std::size_t index, COMPLETION_TOKEN&& token);

private:
std::shared_ptr<http::IHttpClient>
ConstructHttpClient(const ClientConfig& config);

template<typename COMPLETION_SIGNATURE,
typename COMPLETION_TOKEN,
typename FUNCTION,
typename = std::enable_if_t<
std::is_same_v<util::HandlerExtraArgs_t<COMPLETION_SIGNATURE>,
std::tuple<>>>>
void Spawn(FUNCTION&& func, COMPLETION_TOKEN&& token);

template<typename COMPLETION_SIGNATURE,
typename COMPLETION_TOKEN,
typename FUNCTION,
typename EXTRA_ARGS = std::enable_if_t<
(std::tuple_size_v<
util::HandlerExtraArgs_t<COMPLETION_SIGNATURE>> > 0),
util::HandlerExtraArgs_t<COMPLETION_SIGNATURE>>,
typename = void>
void Spawn(FUNCTION&& func, COMPLETION_TOKEN&& token);

private:
struct Functor;

private:
Context ctx_;
std::shared_ptr<http::IHttpClient> http_;
std::shared_ptr<lb::LoadBalancer> lb_;
};

} // namespace opengemini::impl

#include "opengemini/impl/ClientImpl.tpp"
#ifndef OPENGEMINI_SEPARATE_COMPILATION
# include "opengemini/impl/ClientImpl.cpp"
#endif // !OPENGEMINI_SEPARATE_COMPILATION

#endif // !OPENGEMINI_IMPL_CLIENT_HPP
#endif // !OPENGEMINI_IMPL_CLIENTIMPL_HPP
78 changes: 78 additions & 0 deletions include/opengemini/impl/ClientImpl.tpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// Copyright 2024 Huawei Cloud Computing Technologies Co., Ltd.
//
// Licensed 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 "opengemini/impl/ClientImpl.hpp"

#include <boost/exception/diagnostic_information.hpp>

#include "opengemini/impl/cli/Functor.hpp"
#include "opengemini/impl/comm/CompletionSignature.hpp"
#include "opengemini/impl/util/ErrorHandling.hpp"
#include "opengemini/impl/util/TypeTraits.hpp"

namespace opengemini::impl {

template<typename COMPLETION_TOKEN>
auto ClientImpl::Ping(std::size_t index, COMPLETION_TOKEN&& token)
{
using Signature = sig::Ping;
return boost::asio::async_initiate<COMPLETION_TOKEN, Signature>(
[this](auto&& token, std::size_t index) {
static_assert(util::IsInvocable_v<decltype(token), Signature>,
"Completion signature of Ping must be: "
"void(std::exception_ptr, std::string)");

Spawn<Signature>(Functor::RunPing{ this, index },
OPENGEMINI_PF(token));
},
token,
index);
}

template<typename COMPLETION_SIGNATURE,
typename COMPLETION_TOKEN,
typename FUNCTION,
typename>
void ClientImpl::Spawn(FUNCTION&& func, COMPLETION_TOKEN&& token)
{
boost::asio::spawn(ctx_(),
std::forward<FUNCTION>(func),
[_token = std::forward<COMPLETION_TOKEN>(token)](
std::exception_ptr ex) mutable {
_token(util::ConvertException(ex));
});
}

template<typename COMPLETION_SIGNATURE,
typename COMPLETION_TOKEN,
typename FUNCTION,
typename EXTRA_ARGS,
typename>
void ClientImpl::Spawn(FUNCTION&& func, COMPLETION_TOKEN&& token)
{
boost::asio::spawn(
ctx_(),
std::forward<FUNCTION>(func),
[_token = std::forward<COMPLETION_TOKEN>(
token)](std::exception_ptr ex, EXTRA_ARGS args) mutable {
std::apply(
_token,
std::tuple_cat(std::make_tuple(util::ConvertException(ex)),
std::move(args)));
});
}

} // namespace opengemini::impl
Loading

0 comments on commit 17b9dd3

Please sign in to comment.