Синхронный клиент для простых кейсов с простой обработкой ошибок #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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Допустим, мы хотим выполнить запрос BeginTransaction(). Сейчас чтобы это сделать пользователю надо написать вот такой код:
Это простой сценарий, но он требует от пользователя много усилий. Нужен более простой вариант, чтобы скрыть это все от пользователя.
Можно разбить требуемые улучшения на 2 пункта:
Тогда запрос будет выглядеть так:
auto tran = session.BeginTransaction();
Предложение:
Чтобы не трогать уже существующий код, можно сделать новый синхронный клиент
TSimpleTableClient
(название требует доработок). У него будут TSyncSession, у которых будет синхронный API. На ошибках такой клиент будет кидатьTYdbRequestError
. Также можно добавить возможность делать кастомную логику обработку ошибок: в настройкахTSimpleTableClient
будет функцияOnError
, которая по умолчанию будет бросать исключения, но ее можно будет переопределить на клиентской стороне.Также, чтобы уменьшить порог входа и необходимость знания о клиентах, как их подключать, можно поддержать возможность создания
TTableClient
напрямую из драйвера. Тогда код пользователя может выглядеть как-то так:Оставшийся вопрос: как сделать ретраер и как прокинуть в него ошибку
Beta Was this translation helpful? Give feedback.
All reactions