handle all exceptions during async inserts

This commit is contained in:
Anton Popov 2021-08-28 00:46:36 +03:00
parent 9e67943878
commit 7aec53bb8f
3 changed files with 24 additions and 18 deletions

View File

@ -220,7 +220,7 @@ try
insert_context->makeQueryContext();
insert_context->setSettings(data->settings);
InterpreterInsertQuery interpreter(data->query, insert_context, data->settings.insert_allow_materialized_columns, false);
InterpreterInsertQuery interpreter(data->query, insert_context, data->settings.insert_allow_materialized_columns);
auto sinks = interpreter.getSinks();
assert(sinks.size() == 1);
@ -241,12 +241,7 @@ try
if (column->size() > total_rows)
column->popBack(column->size() - total_rows);
std::lock_guard info_lock(current_info->mutex);
current_info->finished = true;
current_info->exception = std::current_exception();
current_info->cv.notify_all();
current_info->complete(std::current_exception());
return 0;
};
@ -286,17 +281,18 @@ try
total_rows, total_bytes, queryToString(data->query));
for (const auto & datum : data->data)
{
std::lock_guard info_lock(datum.info->mutex);
datum.info->finished = true;
datum.info->cv.notify_all();
}
datum.info->complete();
data->reset();
}
catch (...)
{
tryLogCurrentException("AsynchronousInsertQueue", __PRETTY_FUNCTION__);
for (const auto & datum : data->data)
datum.info->complete(std::current_exception());
data->reset();
}
}

View File

@ -927,6 +927,14 @@ void Context::addQueryAccessInfo(
query_access_info.views.emplace(view_name);
}
void Context::AsyncInsertInfo::complete(std::exception_ptr exception_)
{
std::lock_guard lock(mutex);
finished = true;
exception = exception_;
cv.notify_all();
}
Context::AsyncInsertInfoPtr Context::addAsyncInsertQueryId(const String & query_id)
{
auto lock = getLock();
@ -936,7 +944,7 @@ Context::AsyncInsertInfoPtr Context::addAsyncInsertQueryId(const String & query_
void Context::waitForProcessingAsyncInsert(const String & query_id, const std::chrono::milliseconds & timeout) const
{
AsyncInsertInfoPtr wait_data;
AsyncInsertInfoPtr async_info;
{
auto lock = getLock();
@ -944,17 +952,17 @@ void Context::waitForProcessingAsyncInsert(const String & query_id, const std::c
if (it == processing_async_inserts.end())
return;
wait_data = it->second;
async_info = it->second;
}
std::unique_lock lock(wait_data->mutex);
auto finished = wait_data->cv.wait_for(lock, timeout, [&] { return wait_data->finished; });
std::unique_lock lock(async_info->mutex);
auto finished = async_info->cv.wait_for(lock, timeout, [&] { return async_info->finished; });
if (!finished)
throw Exception(ErrorCodes::TIMEOUT_EXCEEDED, "Wait for async insert timeout ({} ms) exceeded)", timeout.count());
if (wait_data->exception)
std::rethrow_exception(wait_data->exception);
if (async_info->exception)
std::rethrow_exception(async_info->exception);
}
void Context::addQueryFactoriesInfo(QueryLogFactories factory_type, const String & created_object) const

View File

@ -292,6 +292,8 @@ public:
std::condition_variable cv;
bool finished = false;
std::exception_ptr exception;
void complete(std::exception_ptr exception_ = nullptr);
};
using AsyncInsertInfoPtr = std::shared_ptr<AsyncInsertInfo>;