Синхронный клиент для простых кейсов с простой обработкой ошибок #340
Replies: 2 comments
-
Вариант 1Основные идеи такие:
Возможный вариант API: namespace NYdb::NTable {
struct TClientSettings : public TCommonClientSettingsBase<TClientSettings> {}; // COMMON???
struct TExecDataQuerySettings : public TOperationRequestSettings<TExecDataQuerySettings> {}; // COMMON???
class TTxSettings; // COMMON???
struct TDataQueryResult {
std::vector<TResultSet> ResultSets;
std::optional<TQueryStats> QueryStats;
};
class TTxHandle {
public:
TDataQueryResult ExecuteDataQuery(const std::string& query, const TExecDataQuerySettings& settings = {});
void Commit();
void Rollback();
};
class TRetryHandle {
public:
void ExecuteInTx(std::function<void(TTxHandle handle)>, const TTxSettings& settings = {});
TDataQueryResult ExecuteDataQuery(const std::string& query, const TExecDataQuerySettings& settings = {});
// ...
};
class TSimpleTableClient {
public:
TSimpleTableClient(const TDriver& driver, const TClientSettings& settings = TClientSettings());
void ExecuteInTx(std::function<void(TTxHandle handle)>, const TTxSettings& settings = {});
void Retry(std::function<void(TRetryHandle handle)>, TDuration timeout);
TDataQueryResult ExecuteDataQuery(const std::string& query,
const TTxSettings& settings = {},
const TExecDataQuerySettings& settings = {});
// ...
void Stop();
private:
class TImpl;
std::shared_ptr<TImpl> Impl_;
};
} Код клиента выполнения одного запроса: NYdb::TDriver driver{"grpc://localhost:2136/local"};
try {
auto result = driver.Table().ExecuteDataQuery("SELECT 1;");
// parse result
} catch (NYdb::TYdbRequestError& e) {
std::cerr << e;
} Код клиента выполнения транзакции с ретраями: NYdb::TDriver driver{"grpc://localhost:2136/local"};
try {
driver.Table().Retry([](TRetryHandle retryHandle) {
retryHandle.ExecuteInTx([](TTxHandle txHandle) {
auto result = txHandle.ExecuteDataQuery("SELECT 1;");
// parse result
});
});
} catch (NYdb::TRequestError& e) {
std::cerr << e;
} |
Beta Was this translation helpful? Give feedback.
-
Вариант 2В отличии от варианта 1, транзакция тут выполнена с помощью RAII (по аналогии с libpqxx). Возможный вариант API: namespace NYdb::NTable {
struct TClientSettings : public TCommonClientSettingsBase<TClientSettings> {}; // COMMON???
struct TExecDataQuerySettings : public TOperationRequestSettings<TExecDataQuerySettings> {}; // COMMON???
struct TTxSettings; // COMMON???
struct TDataQueryResult {
std::vector<TResultSet> ResultSets;
std::optional<TQueryStats> QueryStats;
};
class TTransaction {
public:
TDataQueryResult ExecuteDataQuery(const std::string& query, const TExecDataQuerySettings& settings = {});
void Commit();
void Rollback();
~TTransaction() {
if (IsNeedToCommit_) {
Commit();
}
}
};
class TRetryHandle {
public:
TTransaction BeginTx(const TTxSettings& settings = {});
TDataQueryResult ExecuteDataQuery(const std::string& query,
const TTxSettings& settings = {},
const TExecDataQuerySettings& settings = {});
// ...
};
class TSimpleTableClient {
public:
TSimpleTableClient(const TDriver& driver, const TClientSettings& settings = TClientSettings());
TTransaction BeginTx(const TTxSettings& settings = {});
void Retry(std::function<void(TRetryHandle handle)>, const NRetry::TRetryOperationSettings& settings = {});
TDataQueryResult ExecuteDataQuery(const std::string& query,
const TTxSettings& settings = {},
const TExecDataQuerySettings& settings = {});
// ...
void Stop();
private:
class TImpl;
std::shared_ptr<TImpl> Impl_;
};
} Код клиента выполнения одного запроса: NYdb::TDriver driver{"grpc://localhost:2136/local"};
try {
auto result = driver.Table().ExecuteDataQuery("SELECT 1;");
// parse result
} catch (NYdb::TYdbRequestError& e) {
std::cerr << e;
} Код клиента выполнения транзакции с ретраями: NYdb::TDriver driver{"grpc://localhost:2136/local"};
try {
driver.Table().Retry([](TRetryHandle retryHandle) {
auto tx = retryHandle.BeginTx();
auto result = tx.ExecuteDataQuery("SELECT 1;");
// parse result
});
} catch (NYdb::TYdbRequestError& e) {
std::cerr << e;
} |
Beta Was this translation helpful? Give feedback.
-
Допустим, мы хотим выполнить запрос BeginTransaction(). Сейчас чтобы это сделать пользователю надо написать вот такой код:
Это простой сценарий, но он требует от пользователя много усилий. Нужен более простой вариант, чтобы скрыть это все от пользователя.
Можно разбить требуемые улучшения на 2 пункта:
Тогда запрос будет выглядеть так:
auto tran = session.BeginTransaction();
Предложение:
Чтобы не трогать уже существующий код, можно сделать новый синхронный клиент
TSimpleTableClient
(название требует доработок). У него будут TSyncSession, у которых будет синхронный API. На ошибках такой клиент будет кидатьTYdbRequestError
. Также можно добавить возможность делать кастомную логику обработку ошибок: в настройкахTSimpleTableClient
будет функцияOnError
, которая по умолчанию будет бросать исключения, но ее можно будет переопределить на клиентской стороне.Также, чтобы уменьшить порог входа и необходимость знания о клиентах, как их подключать, можно поддержать возможность создания
TTableClient
напрямую из драйвера. Тогда код пользователя может выглядеть как-то так:Оставшийся вопрос: как сделать ретраер и как прокинуть в него ошибку
Beta Was this translation helpful? Give feedback.
All reactions