2011-11-28 05:48:52 +00:00
|
|
|
#pragma once
|
|
|
|
|
2012-10-20 05:36:32 +00:00
|
|
|
#include <Poco/Event.h>
|
2011-11-28 05:48:52 +00:00
|
|
|
|
2019-01-23 14:48:50 +00:00
|
|
|
#include <DataStreams/IBlockInputStream.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Common/CurrentMetrics.h>
|
2019-01-11 19:12:36 +00:00
|
|
|
#include <Common/ThreadPool.h>
|
2011-11-28 05:48:52 +00:00
|
|
|
|
|
|
|
|
2016-10-24 04:06:27 +00:00
|
|
|
namespace CurrentMetrics
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
extern const Metric QueryThread;
|
2016-10-24 04:06:27 +00:00
|
|
|
}
|
|
|
|
|
2011-11-28 05:48:52 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Executes another BlockInputStream in a separate thread.
|
|
|
|
* This serves two purposes:
|
|
|
|
* 1. Allows you to make the different stages of the query execution pipeline work in parallel.
|
|
|
|
* 2. Allows you not to wait until the data is ready, and periodically check their readiness without blocking.
|
|
|
|
* This is necessary, for example, so that during the waiting period you can check if a packet
|
|
|
|
* has come over the network with a request to interrupt the execution of the query.
|
|
|
|
* It also allows you to execute multiple queries at the same time.
|
2012-10-20 02:10:47 +00:00
|
|
|
*/
|
2019-01-23 14:48:50 +00:00
|
|
|
class AsynchronousBlockInputStream : public IBlockInputStream
|
2012-10-20 02:10:47 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-09-08 02:29:47 +00:00
|
|
|
AsynchronousBlockInputStream(const BlockInputStreamPtr & in)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2017-09-08 02:29:47 +00:00
|
|
|
children.push_back(in);
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
String getName() const override { return "Asynchronous"; }
|
|
|
|
|
|
|
|
void readPrefix() override
|
|
|
|
{
|
2017-05-13 22:19:04 +00:00
|
|
|
/// Do not call `readPrefix` on the child, so that the corresponding actions are performed in a separate thread.
|
2017-04-01 07:20:54 +00:00
|
|
|
if (!started)
|
|
|
|
{
|
|
|
|
next();
|
|
|
|
started = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void readSuffix() override
|
|
|
|
{
|
|
|
|
if (started)
|
|
|
|
{
|
|
|
|
pool.wait();
|
2017-09-13 18:09:21 +00:00
|
|
|
if (exception)
|
|
|
|
std::rethrow_exception(exception);
|
2017-04-01 07:20:54 +00:00
|
|
|
children.back()->readSuffix();
|
2017-09-13 18:09:21 +00:00
|
|
|
started = false;
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/** Wait for the data to be ready no more than the specified timeout. Start receiving data if necessary.
|
|
|
|
* If the function returned true - the data is ready and you can do `read()`; You can not call the function just at the same moment again.
|
2017-04-01 07:20:54 +00:00
|
|
|
*/
|
|
|
|
bool poll(UInt64 milliseconds)
|
|
|
|
{
|
|
|
|
if (!started)
|
|
|
|
{
|
|
|
|
next();
|
|
|
|
started = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ready.tryWait(milliseconds);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-02-18 03:23:48 +00:00
|
|
|
Block getHeader() const override { return children.at(0)->getHeader(); }
|
2018-01-06 18:10:44 +00:00
|
|
|
|
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
~AsynchronousBlockInputStream() override
|
|
|
|
{
|
2017-09-13 18:09:21 +00:00
|
|
|
if (started)
|
|
|
|
pool.wait();
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2012-03-05 02:34:20 +00:00
|
|
|
|
2011-11-28 05:48:52 +00:00
|
|
|
protected:
|
2017-09-13 18:09:21 +00:00
|
|
|
ThreadPool pool{1};
|
2017-04-01 07:20:54 +00:00
|
|
|
Poco::Event ready;
|
|
|
|
bool started = false;
|
|
|
|
bool first = true;
|
|
|
|
|
|
|
|
Block block;
|
2017-09-13 18:09:21 +00:00
|
|
|
std::exception_ptr exception;
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2018-06-01 11:58:17 +00:00
|
|
|
Block readImpl() override;
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2018-06-01 11:58:17 +00:00
|
|
|
void next();
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2017-05-13 22:19:04 +00:00
|
|
|
/// Calculations that can be performed in a separate thread
|
2018-06-01 11:58:17 +00:00
|
|
|
void calculate();
|
2011-11-28 05:48:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|