143 lines
2.9 KiB
C++
143 lines
2.9 KiB
C++
|
|
#include "message_bus/pipeline/PipelineEngine.h"
|
||
|
|
|
||
|
|
#include <chrono>
|
||
|
|
|
||
|
|
#include "utils/logs/logging.h"
|
||
|
|
|
||
|
|
namespace softbus::message_bus::pipeline
|
||
|
|
{
|
||
|
|
|
||
|
|
PipelineEngine::PipelineEngine(std::size_t queueCapacity)
|
||
|
|
: m_ingressQ(queueCapacity), m_egressQ(queueCapacity)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
PipelineEngine::~PipelineEngine()
|
||
|
|
{
|
||
|
|
stop();
|
||
|
|
}
|
||
|
|
|
||
|
|
void PipelineEngine::start()
|
||
|
|
{
|
||
|
|
if (m_running.exchange(true)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
m_worker = std::thread([this]() { run(); });
|
||
|
|
}
|
||
|
|
|
||
|
|
void PipelineEngine::stop()
|
||
|
|
{
|
||
|
|
if (!m_running.exchange(false)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (m_worker.joinable()) {
|
||
|
|
m_worker.join();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void PipelineEngine::drain()
|
||
|
|
{
|
||
|
|
PipelineContext tmp;
|
||
|
|
while (m_ingressQ.pop(tmp)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PipelineEngine::enqueueIngress(PipelineContext ctx)
|
||
|
|
{
|
||
|
|
if (!m_ingressQ.push(std::move(ctx))) {
|
||
|
|
++m_counters.drop;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
++m_counters.in;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PipelineEngine::enqueueEgress(PipelineContext ctx)
|
||
|
|
{
|
||
|
|
return m_egressQ.push(std::move(ctx));
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PipelineEngine::tryPopEgress(PipelineContext& out)
|
||
|
|
{
|
||
|
|
return m_egressQ.pop(out);
|
||
|
|
}
|
||
|
|
|
||
|
|
void PipelineEngine::setPluginManager(std::shared_ptr<softbus::core::plugin_system::PluginManager> pluginManager)
|
||
|
|
{
|
||
|
|
m_pluginManager = std::move(pluginManager);
|
||
|
|
}
|
||
|
|
|
||
|
|
void PipelineEngine::run()
|
||
|
|
{
|
||
|
|
while (m_running.load()) {
|
||
|
|
PipelineContext ctx;
|
||
|
|
if (!m_ingressQ.pop(ctx)) {
|
||
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
const bool framed = stage1Framer(ctx);
|
||
|
|
const bool parsed = framed && stage2Parser(ctx);
|
||
|
|
const bool filtered = parsed && stage3Filter(ctx);
|
||
|
|
const bool valid = filtered && stage4Validator(ctx);
|
||
|
|
if (!valid) {
|
||
|
|
++m_counters.error;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (!m_egressQ.push(std::move(ctx))) {
|
||
|
|
++m_counters.drop;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
++m_counters.out;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PipelineEngine::stage1Framer(PipelineContext& ctx)
|
||
|
|
{
|
||
|
|
if (!ctx.payload.valid()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (ctx.payloadSize == 0) {
|
||
|
|
ctx.payloadSize = ctx.payload.length;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PipelineEngine::stage4Validator(PipelineContext& ctx)
|
||
|
|
{
|
||
|
|
if (!ctx.payload.valid()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (ctx.endpoint.isEmpty()) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (!ctx.timestamp.isValid()) {
|
||
|
|
ctx.timestamp = QDateTime::currentDateTimeUtc();
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PipelineEngine::stage2Parser(PipelineContext& ctx)
|
||
|
|
{
|
||
|
|
if (!m_pluginManager) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
auto plugin = m_pluginManager->selectProtocolPlugin(ctx.protocolHint);
|
||
|
|
if (!plugin) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
auto session = plugin->createSession();
|
||
|
|
if (!session) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return session->feed(ctx);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PipelineEngine::stage3Filter(PipelineContext& ctx)
|
||
|
|
{
|
||
|
|
(void)ctx;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace softbus::message_bus::pipeline
|