Fix crashing bug related to account_tx writes

This commit is contained in:
CJ Cobb
2021-05-03 21:16:25 +00:00
parent c0612e740e
commit 4e58c76eac
2 changed files with 49 additions and 29 deletions

View File

@@ -24,12 +24,13 @@ processAsyncWriteResponse(T& requestParams, CassFuture* fut, F func)
auto rc = cass_future_error_code(fut); auto rc = cass_future_error_code(fut);
if (rc != CASS_OK) if (rc != CASS_OK)
{ {
BOOST_LOG_TRIVIAL(error)
<< "ERROR!!! Cassandra insert error: " << rc << ", "
<< cass_error_desc(rc) << ", retrying ";
// exponential backoff with a max wait of 2^10 ms (about 1 second) // exponential backoff with a max wait of 2^10 ms (about 1 second)
auto wait = std::chrono::milliseconds( auto wait = std::chrono::milliseconds(
lround(std::pow(2, std::min(10u, requestParams.currentRetries)))); lround(std::pow(2, std::min(10u, requestParams.currentRetries))));
BOOST_LOG_TRIVIAL(error)
<< "ERROR!!! Cassandra ETL insert error: " << rc << ", "
<< cass_error_desc(rc) << ", retrying in " << wait.count()
<< " milliseconds";
++requestParams.currentRetries; ++requestParams.currentRetries;
std::shared_ptr<boost::asio::steady_timer> timer = std::shared_ptr<boost::asio::steady_timer> timer =
std::make_shared<boost::asio::steady_timer>( std::make_shared<boost::asio::steady_timer>(
@@ -42,6 +43,8 @@ processAsyncWriteResponse(T& requestParams, CassFuture* fut, F func)
} }
else else
{ {
BOOST_LOG_TRIVIAL(trace)
<< __func__ << " Succesfully inserted a record";
backend.finishAsyncWrite(); backend.finishAsyncWrite();
int remaining = --requestParams.refs; int remaining = --requestParams.refs;
if (remaining == 0) if (remaining == 0)
@@ -668,12 +671,13 @@ writeBookCallback(CassFuture* fut, void* cbData)
auto rc = cass_future_error_code(fut); auto rc = cass_future_error_code(fut);
if (rc != CASS_OK) if (rc != CASS_OK)
{ {
BOOST_LOG_TRIVIAL(error)
<< "ERROR!!! Cassandra insert key error: " << rc << ", "
<< cass_error_desc(rc) << ", retrying ";
// exponential backoff with a max wait of 2^10 ms (about 1 second) // exponential backoff with a max wait of 2^10 ms (about 1 second)
auto wait = std::chrono::milliseconds( auto wait = std::chrono::milliseconds(
lround(std::pow(2, std::min(10u, requestParams.currentRetries)))); lround(std::pow(2, std::min(10u, requestParams.currentRetries))));
BOOST_LOG_TRIVIAL(error)
<< "ERROR!!! Cassandra insert book error: " << rc << ", "
<< cass_error_desc(rc) << ", retrying in " << wait.count()
<< " milliseconds";
++requestParams.currentRetries; ++requestParams.currentRetries;
std::shared_ptr<boost::asio::steady_timer> timer = std::shared_ptr<boost::asio::steady_timer> timer =
std::make_shared<boost::asio::steady_timer>( std::make_shared<boost::asio::steady_timer>(
@@ -686,7 +690,7 @@ writeBookCallback(CassFuture* fut, void* cbData)
} }
else else
{ {
BOOST_LOG_TRIVIAL(trace) << __func__ << "Finished a write request"; BOOST_LOG_TRIVIAL(trace) << __func__ << " Successfully inserted a book";
{ {
std::lock_guard lck(requestParams.mtx); std::lock_guard lck(requestParams.mtx);
--requestParams.numRemaining; --requestParams.numRemaining;
@@ -742,12 +746,13 @@ writeKeyCallback(CassFuture* fut, void* cbData)
auto rc = cass_future_error_code(fut); auto rc = cass_future_error_code(fut);
if (rc != CASS_OK) if (rc != CASS_OK)
{ {
BOOST_LOG_TRIVIAL(error)
<< "ERROR!!! Cassandra insert key error: " << rc << ", "
<< cass_error_desc(rc) << ", retrying ";
// exponential backoff with a max wait of 2^10 ms (about 1 second)
auto wait = std::chrono::milliseconds( auto wait = std::chrono::milliseconds(
lround(std::pow(2, std::min(10u, requestParams.currentRetries)))); lround(std::pow(2, std::min(10u, requestParams.currentRetries))));
BOOST_LOG_TRIVIAL(error)
<< "ERROR!!! Cassandra insert key error: " << rc << ", "
<< cass_error_desc(rc) << ", retrying in " << wait.count()
<< " milliseconds";
// exponential backoff with a max wait of 2^10 ms (about 1 second)
++requestParams.currentRetries; ++requestParams.currentRetries;
std::shared_ptr<boost::asio::steady_timer> timer = std::shared_ptr<boost::asio::steady_timer> timer =
std::make_shared<boost::asio::steady_timer>( std::make_shared<boost::asio::steady_timer>(
@@ -760,7 +765,7 @@ writeKeyCallback(CassFuture* fut, void* cbData)
} }
else else
{ {
BOOST_LOG_TRIVIAL(trace) << __func__ << "Finished a write request"; BOOST_LOG_TRIVIAL(trace) << __func__ << " Successfully inserted a key";
{ {
std::lock_guard lck(requestParams.mtx); std::lock_guard lck(requestParams.mtx);
--requestParams.numRemaining; --requestParams.numRemaining;

View File

@@ -1185,18 +1185,29 @@ public:
{ {
} }
}; };
struct WriteAccountTxCallbackData struct WriteAccountTxCallbackData
{ {
CassandraBackend const* backend; CassandraBackend const* backend;
AccountTransactionsData data; ripple::AccountID account;
uint32_t ledgerSequence;
uint32_t transactionIndex;
ripple::uint256 txHash;
uint32_t currentRetries = 0; uint32_t currentRetries = 0;
std::atomic<int> refs; std::atomic<int> refs = 1;
WriteAccountTxCallbackData( WriteAccountTxCallbackData(
CassandraBackend const* f, CassandraBackend const* f,
AccountTransactionsData&& in) ripple::AccountID&& account,
: backend(f), data(std::move(in)), refs(data.accounts.size()) uint32_t lgrSeq,
uint32_t txIdx,
ripple::uint256&& hash)
: backend(f)
, account(std::move(account))
, ledgerSequence(lgrSeq)
, transactionIndex(txIdx)
, txHash(std::move(hash))
{ {
} }
}; };
@@ -1291,26 +1302,30 @@ public:
{ {
for (auto& record : data) for (auto& record : data)
{ {
WriteAccountTxCallbackData* cbData = for (auto& account : record.accounts)
new WriteAccountTxCallbackData(this, std::move(record)); {
writeAccountTx(*cbData, false); WriteAccountTxCallbackData* cbData =
new WriteAccountTxCallbackData(
this,
std::move(account),
record.ledgerSequence,
record.transactionIndex,
std::move(record.txHash));
writeAccountTx(*cbData, false);
}
} }
} }
void void
writeAccountTx(WriteAccountTxCallbackData& data, bool isRetry) const writeAccountTx(WriteAccountTxCallbackData& data, bool isRetry) const
{ {
for (auto const& account : data.data.accounts) CassandraStatement statement(insertAccountTx_);
{ statement.bindBytes(data.account);
CassandraStatement statement(insertAccountTx_); statement.bindIntTuple(data.ledgerSequence, data.transactionIndex);
statement.bindBytes(account); statement.bindBytes(data.txHash);
statement.bindIntTuple(
data.data.ledgerSequence, data.data.transactionIndex);
statement.bindBytes(data.data.txHash);
executeAsyncWrite( executeAsyncWrite(
statement, flatMapWriteAccountTxCallback, data, isRetry); statement, flatMapWriteAccountTxCallback, data, isRetry);
}
} }
struct WriteTransactionCallbackData struct WriteTransactionCallbackData