-
Notifications
You must be signed in to change notification settings - Fork 303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat etcd: Init etcd client #837
base: develop
Are you sure you want to change the base?
Conversation
#include <userver/components/component_config.hpp> | ||
#include <userver/components/component_context.hpp> | ||
#include <userver/storages/etcd/client.hpp> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
во все публичные хедеры нужно добавить документацию
в заголовок файла
перед каждым классом
перед каждым методом
|
||
namespace storages::etcd { | ||
|
||
class Client final { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
может лучше не final, а абстрактный класс? чтобы можно было замокать для тестирования клиента конфигов с использованием etcd
|
||
struct ClientSettings final { | ||
std::vector<std::string> endpoints; | ||
std::uint32_t retries; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attempts
etcd/src/storages/etcd/client.cpp
Outdated
} | ||
|
||
std::string BuildPutData(const std::string& key, const std::string& value) { | ||
formats::json::StringBuilder sb; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут скорость не так важна
можно и просто из inline.hpp взять MakeObject("key", x, "value", y)
etcd/src/storages/etcd/component.cpp
Outdated
minimum: 1 | ||
request_timeout_ms: | ||
type: integer | ||
description: Number of miliseconds to timeout request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
between request attempts
Client(clients::http::Client& http_client, ClientSettings settings); | ||
void Put(const std::string& key, const std::string& value); | ||
[[nodiscard]] std::vector<std::string> Range(const std::string& key); | ||
void DeleteRange(const std::string& key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
для клиента конфигов нам нужны:
- получение значения по ключу
- получение всех значений (это range&)
- вотч на все значения
возможно не все, а только те, что начинаются с определенного префикса
Client(clients::http::Client& http_client, ClientSettings settings); | ||
void Put(const std::string& key, const std::string& value); | ||
[[nodiscard]] std::vector<std::string> Range(const std::string& key); | ||
void DeleteRange(const std::string& key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
для клиента конфигов очень хочется иметь юнит-тест
Client(clients::http::Client& http_client, ClientSettings settings); | ||
void Put(const std::string& key, const std::string& value); | ||
[[nodiscard]] std::vector<std::string> Range(const std::string& key); | ||
void DeleteRange(const std::string& key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
для клиента конфигов очень хочется иметь testsuite-тест, который получает значения конфига из мока
etcd/src/storages/etcd/client.cpp
Outdated
return sb.GetString(); | ||
} | ||
|
||
bool ShouldRetry(std::shared_ptr<clients::http::Response> response) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут что-то должно быть? для того, чтобы фолбечиться на другой бекенд при отказе одно
@@ -0,0 +1,63 @@ | |||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
без storages/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Убрал
|
||
USERVER_NAMESPACE_BEGIN | ||
|
||
namespace storages::etcd { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
без storages
|
||
class Component final : public components::ComponentBase { | ||
public: | ||
static constexpr std::string_view kName = "etcd"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
etcd-client
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Поправил
|
||
Component(const components::ComponentConfig&, const components::ComponentContext&); | ||
|
||
~Component() = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
не нужно
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Убрал
|
||
namespace storages::etcd { | ||
|
||
struct KVEvent final { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KeyValueEvent, не нужно сокращать такие короткие имена
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Поправил
etcd/src/storages/etcd/client.cpp
Outdated
"watch task", | ||
[stream_response = std::move(stream_response), produser = queue->GetProducer()] mutable { | ||
std::string body_part; | ||
const auto deadline = engine::Deadline::FromDuration(std::chrono::seconds{100'000'000}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
можно просто не указывать дедлайн
etcd/src/storages/etcd/client.cpp
Outdated
const auto watch_response = formats::json::FromString(body_part); | ||
LOG_ERROR() << watch_response; | ||
if (!watch_response["result"].HasMember("events")) { | ||
LOG_INFO() << "No events in watch part response, skipping"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
дебаг
etcd/src/storages/etcd/client.cpp
Outdated
} | ||
const auto key = crypto::base64::Base64Decode(event["kv"]["key"].As<std::string>()); | ||
const auto value = crypto::base64::Base64Decode(event["kv"]["value"].As<std::string>()); | ||
const auto version = std::stoi(event["kv"]["version"].As<std::string>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
парсинг евента нужно точно через chaotic делать
etcd/src/storages/etcd/client.cpp
Outdated
.CreateRequest() | ||
.post(url_builder(endpoint), data) | ||
.retry(settings_.retries) | ||
.timeout(1'000'000'000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
в статический конфиг
#pragma once | ||
|
||
#include <chrono> | ||
#include <cstdint> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
давай сразу клиента конфига сделаешь до полноценного watch event'а - так будет проще понять, какой API требуется и что еще необходимо сделать
etcd/src/etcd/client_impl.cpp
Outdated
.timeout(1'000'000'000) | ||
.async_perform_stream_body(queue); | ||
if (!ShouldRetry(stream_response.StatusCode())) { | ||
CheckRequestStatusCode(stream_response.StatusCode()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stream_response.RaiseForError()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Кажется, для StreamedResponse нет такого метода
etcd/src/etcd/client_impl.cpp
Outdated
auto stream_response = http_client_.CreateRequest() | ||
.post(url_builder(endpoint), data) | ||
.retry(settings_.attempts) | ||
.timeout(1'000'000'000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
какая будет защита от залипшего соединения?
в целом, можно отдельно про это подумать
etcd/src/etcd/client_impl.cpp
Outdated
return stream_response; | ||
} | ||
} | ||
throw EtcdError("Failed to get Ok response from etcd"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
а ошибка какая? или хотя бы статус код(ы) какой?
etcd/src/etcd/client_impl.cpp
Outdated
return response; | ||
} | ||
} | ||
throw EtcdError("Failed to get Ok response from etcd"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
аналогично, мало информации об ошибке
); | ||
|
||
clients::http::Client& http_client_; | ||
engine::Mutex watch_queues_lock_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
concurrent::Variable
etcd/src/etcd/client_impl.hpp
Outdated
|
||
class ClientImpl : public Client { | ||
public: | ||
~ClientImpl() override = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
override = default выглядит странно
public: | ||
~ClientImpl() override = default; | ||
ClientImpl(clients::http::Client& http_client, ClientSettings settings); | ||
void Put(const std::string& key, const std::string& value) override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
разделяй методы пустой строкой
etcd/src/etcd/client_impl.cpp
Outdated
if (!event.HasMember("kv")) { | ||
continue; | ||
} | ||
if (!produser.PushNoblock(event["kv"].As<KeyValueEvent>())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
почему Noblock?
utils::Async("watch task", [stream_response = std::move(stream_response), produser = queue->GetProducer()] mutable { | ||
std::string body_part; | ||
const auto deadline = engine::Deadline::FromDuration(std::chrono::seconds{100'000'000}); | ||
while (stream_response.ReadChunk(body_part, deadline)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
давай передавать распаршенное тело
лучше разделить парсинг и интерпретацию ответов
etcd/src/etcd/client_impl.cpp
Outdated
watch_queues_.push_back(queue); | ||
watch_queues_lock_.unlock(); | ||
|
||
utils::Async("watch task", [stream_response = std::move(stream_response), produser = queue->GetProducer()] mutable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
produCer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Поправил
Note: by creating a PR or an issue you automatically agree to the CLA. See CONTRIBUTING.md. Feel free to remove this note, the agreement holds.