#include "message_bus/pipeline/PipelineEngine.h" #include #include #include #include #include #include "message_bus/pipeline/stages/3_filters/ProtocolParseFilter.h" #include "utils/logs/logging.h" namespace softbus::message_bus::pipeline { struct EndpointFramingState { softbus::core::memory::LockFreeQueue chunkQ; std::atomic running{true}; std::thread th; std::uint64_t nextSeq{1}; QString endpoint; std::shared_ptr pool; std::function&)> feed; std::function pushFramed; explicit EndpointFramingState(std::size_t cap) : chunkQ(cap) { } }; namespace { void endpointFramerThread(std::shared_ptr st) { while (st->running.load(std::memory_order_acquire)) { softbus::core::models::RawBusMessage ch; if (!st->chunkQ.pop(ch)) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); continue; } std::vector out; if (st->feed) { st->feed(ch, out); } for (auto& x : out) { const std::uint64_t seq = st->nextSeq++; if (st->pushFramed) { st->pushFramed(st->endpoint, seq, std::move(x)); } } } } } // namespace PipelineEngine::PipelineEngine(std::size_t queueCapacity) : m_ingressQ(queueCapacity) , m_egressQ(queueCapacity) { } PipelineEngine::~PipelineEngine() { stop(); } void PipelineEngine::setMemoryPool(std::shared_ptr pool) { m_pool = std::move(pool); } void PipelineEngine::setRuntimeConfig(PipelineRuntimeConfig cfg) { m_rtConfig = cfg; } void PipelineEngine::loadRuntimeConfigFromJson(const QJsonObject& obj) { if (obj.isEmpty()) { LOG_ERROR() << "PipelineEngine: runtime config is empty"; // return; } m_rtConfig.parallelPipeline = obj.value(QStringLiteral("parallelPipeline")).toBool(true); m_rtConfig.parseWorkerCount = std::max(1, obj.value(QStringLiteral("parseWorkerCount")).toInt(2)); m_rtConfig.orderedEgress = obj.value(QStringLiteral("orderedEgress")).toBool(true); m_rtConfig.framedQueueMax = static_cast( std::max(64, obj.value(QStringLiteral("framedQueueMax")).toInt(4096))); m_rtConfig.maxReorderDepth = static_cast( std::max(16, obj.value(QStringLiteral("maxReorderDepth")).toInt(256))); } void PipelineEngine::start() { if (m_running.exchange(true)) { return; } if (!m_pool) { LOG_ERROR() << "PipelineEngine::start: memory pool not set"; m_running = false; return; } m_passthroughFramer = std::make_shared(m_pool); // 如果启用并行管道 则创建帧队列和解析线程 如果启用有序出口 则创建合并队列和合并线程 // 并行管道是用来处理多个端点的数据流的 // 有序出口是用来保证数据流的有序性的 // 帧队列是用来存储帧的 // 解析线程是用来处理帧的 // 合并队列是用来存储合并的帧的 // 合并线程是用来处理合并的帧的 if (m_rtConfig.parallelPipeline) { m_framedQ = std::make_unique>(m_rtConfig.framedQueueMax); for (int i = 0; i < m_rtConfig.parseWorkerCount; ++i) { // 创建解析线程 解析线程从帧队列中取出帧 进行处理 // emplace_back 是用来创建解析线程的 参数是 lambda 表达式 // [this]() { parseWorkerLoop(); } 是一个 lambda 表达式 用来创建解析线程 m_parseThreads.emplace_back([this]() { parseWorkerLoop(); }); } if (m_rtConfig.orderedEgress) { m_mergeQ = std::make_unique>(0); m_mergerThread = std::thread([this]() { mergerLoop(); }); } } else { m_worker = std::thread([this]() { runSingleWorker(); }); } } void PipelineEngine::stop() { if (!m_running.exchange(false)) { return; } { std::lock_guard lk(m_endpointMutex); for (auto it = m_endpointFramers.constBegin(); it != m_endpointFramers.constEnd(); ++it) { if (it.value()) { it.value()->running.store(false, std::memory_order_release); } } for (auto it = m_endpointFramers.constBegin(); it != m_endpointFramers.constEnd(); ++it) { if (it.value() && it.value()->th.joinable()) { it.value()->th.join(); } } m_endpointFramers.clear(); } if (m_worker.joinable()) { m_worker.join(); } for (auto& t : m_parseThreads) { if (t.joinable()) { t.join(); } } m_parseThreads.clear(); if (m_mergerThread.joinable()) { m_mergerThread.join(); } m_framedQ.reset(); m_mergeQ.reset(); m_passthroughFramer.reset(); { std::lock_guard lk(m_framerSessionMutex); m_framerSessions.clear(); } { std::lock_guard lk(m_parserSessionMutex); m_parserSessions.clear(); } { std::lock_guard lk(m_mapperSessionMutex); m_mapperSessions.clear(); } } // 功能 :清空 ingress 队列 // 参数 :无 // 返回值 :无 // 逻辑 :从 ingress 队列中取出数据 直到队列为空 void PipelineEngine::drain() { softbus::core::models::RawBusMessage tmp; while (m_ingressQ.pop(tmp)) { } } // 功能 :将数据推送到 ingress 队列 // 参数 :ctx 数据 // 返回值 :是否成功 // 逻辑 :如果并行管道启用 则根据端点确保帧解析器 然后推送到帧队列 如果并行管道未启用 则直接推送到 ingress 队列 bool PipelineEngine::enqueueIngress(softbus::core::models::RawBusMessage ctx) { if (m_rtConfig.parallelPipeline) { if (ctx.endpoint.isEmpty()) { ++m_counters.drop; return false; } ensureEndpointFramer(ctx.endpoint); std::shared_ptr st; { std::lock_guard lk(m_endpointMutex); st = m_endpointFramers.value(ctx.endpoint); } if (!st || !st->chunkQ.push(std::move(ctx))) { ++m_counters.drop; return false; } ++m_counters.in; return true; } if (!m_ingressQ.push(std::move(ctx))) { ++m_counters.drop; return false; } ++m_counters.in; return true; } // 功能 :将数据推送到 egress 队列 // 参数 :ctx 数据 // 返回值 :是否成功 // 逻辑 :将数据推送到 egress 队列 bool PipelineEngine::enqueueEgress(softbus::core::models::RawBusMessage ctx) { return m_egressQ.push(std::move(ctx)); } // 功能 :尝试从 egress 队列中取出数据 // 参数 :out 数据 // 返回值 :是否成功 // 逻辑 :从 egress 队列中取出数据 如果队列为空 则返回false 如果队列不为空 则返回true bool PipelineEngine::tryPopEgress(softbus::core::models::RawBusMessage& out) { return m_egressQ.pop(out); } // 功能 :设置插件管理器 // 参数 :pluginManager 插件管理器 // 返回值 :无 // 逻辑 :设置插件管理器 void PipelineEngine::setPluginManager(std::shared_ptr pluginManager) { m_pluginManager = std::move(pluginManager); } // 功能 :确保端点帧解析器 // 参数 :endpoint 端点 // 返回值 :无 // 逻辑 :如果端点帧解析器不存在 则创建端点帧解析器 void PipelineEngine::ensureEndpointFramer(const QString& endpoint) { std::lock_guard lk(m_endpointMutex); if (m_endpointFramers.contains(endpoint)) { return; } const std::size_t qcap = m_ingressQ.capacity(); auto st = std::make_shared(qcap > 0 ? qcap : 4096); st->endpoint = endpoint; st->pool = m_pool; st->feed = [this](softbus::core::models::RawBusMessage& in, std::vector& out) { this->dispatchFramer(in, out); }; st->pushFramed = [this](QString endpoint, std::uint64_t seq, softbus::core::models::RawBusMessage c) { if (!m_framedQ) { return; } MergeItem item; item.endpoint = std::move(endpoint); item.seq = seq; item.ctx = std::move(c); item.pipelineOk = true; if (!m_framedQ->tryPush(std::move(item))) { ++m_counters.drop; LOG_WARNING() << "PipelineEngine: framed queue full drop"; } }; st->th = std::thread(endpointFramerThread, st); m_endpointFramers.insert(endpoint, std::move(st)); } // 功能 :分发帧解析器 // 参数 :chunkIn 数据 // 返回值 :无 // 逻辑 :根据协议提示 选择合适的帧解析器 进行帧解析 void PipelineEngine::dispatchFramer( softbus::core::models::RawBusMessage& chunkIn, std::vector& completeFramesOut) { if (m_pluginManager) { auto plugin = m_pluginManager->selectProtocolFramerPlugin(chunkIn.protocolHint); if (plugin) { plugin->bindMemoryPool(m_pool); const QString key = chunkIn.endpoint + QStringLiteral("|") + plugin->pluginId(); std::lock_guard lk(m_framerSessionMutex); auto it = m_framerSessions.find(key); if (it == m_framerSessions.end() || !it.value()) { auto s = plugin->createFramerSession(chunkIn.endpoint, QJsonObject{}); m_framerSessions.insert( key, s ? std::shared_ptr(std::move(s)) : nullptr); it = m_framerSessions.find(key); } if (it != m_framerSessions.end() && it.value()) { it.value()->feedChunk(chunkIn, completeFramesOut); return; } } } if (m_passthroughFramer) { m_passthroughFramer->feed(chunkIn, completeFramesOut); } } // 功能 :分配帧序列号 std::uint64_t PipelineEngine::assignFrameSequence(const QString& endpoint) { std::lock_guard lk(m_seqMutex); return ++m_nextFrameSeqByEndpoint[endpoint]; } void PipelineEngine::runSingleWorker() { // 单线程工作线程 从 ingress 队列中取出数据 进行处理 然后推送到 egress 队列中 while (m_running.load(std::memory_order_acquire)) { softbus::core::models::RawBusMessage ctx; if (!m_ingressQ.pop(ctx)) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); continue; } std::vector batch; dispatchFramer(ctx, batch); for (auto& c : batch) { // std::ostringstream oss; oss << std::hex << std::setfill('0'); for (std::size_t i = 0; i < c.payload.block->size; ++i) { oss << std::setw(2) << static_cast(c.payload.block->data[i]); if (i + 1 < c.payload.block->size) { oss << ' '; } } const QString hexPreview = QString::fromStdString(oss.str()); LOG_INFO() << "the data is"<< hexPreview; // 分配帧序列号 const bool ok = runStages234(c); if (!ok) { ++m_counters.error; continue; } if (!m_egressQ.push(std::move(c))) { ++m_counters.drop; continue; } ++m_counters.out; } } } void PipelineEngine::parseWorkerLoop() { while (true) { MergeItem item; const bool have = m_framedQ && m_framedQ->popWaitFor(item, m_running, std::chrono::milliseconds(50)); if (!have) { if (!m_running.load(std::memory_order_acquire)) { break; } continue; } const bool ok = runStages234(item.ctx); if (m_rtConfig.orderedEgress && m_mergeQ) { item.pipelineOk = ok; m_mergeQ->push(std::move(item)); } else { if (!ok) { ++m_counters.error; continue; } if (!m_egressQ.push(std::move(item.ctx))) { ++m_counters.drop; continue; } ++m_counters.out; } } } void PipelineEngine::mergerLoop() { while (true) { MergeItem it; const bool have = m_mergeQ && m_mergeQ->popWaitFor(it, m_running, std::chrono::milliseconds(50)); if (!have) { if (!m_running.load(std::memory_order_acquire)) { break; } continue; } ingestMergeItem(std::move(it)); } } // 功能 :合并帧 // 参数 :item 合并项 // 返回值 :无 // 逻辑 :将合并项中的数据推送到 egress 队列中 void PipelineEngine::ingestMergeItem(MergeItem item) { std::lock_guard lk(m_mergeStateMutex); auto& st = m_mergeByEndpoint[item.endpoint]; if (m_rtConfig.maxReorderDepth > 0 && static_cast(st.buffer.size()) >= m_rtConfig.maxReorderDepth) { ++m_counters.mergeDrop; LOG_WARNING() << "PipelineEngine: merge reorder depth exceeded endpoint=" << item.endpoint; return; } st.buffer.insert(item.seq, std::make_pair(std::move(item.ctx), item.pipelineOk)); while (st.buffer.contains(st.nextExpected)) { auto pr = st.buffer.take(st.nextExpected); ++st.nextExpected; const bool pipelineOk = pr.second; softbus::core::models::RawBusMessage ctx = std::move(pr.first); if (!pipelineOk) { ++m_counters.error; continue; } if (!m_egressQ.push(std::move(ctx))) { ++m_counters.drop; continue; } ++m_counters.out; } } // 功能 :运行阶段234 // 参数 :ctx 数据 // 返回值 :是否成功 // 逻辑 :如果帧类型不是完整帧 则返回false 如果阶段2解析失败 则返回false 如果阶段3过滤失败 则返回false 如果阶段4验证失败 则返回false 如果都成功 则返回true bool PipelineEngine::runStages234(const softbus::core::models::RawBusMessage& ctx) { auto messages = stage2Parser(ctx); LOG_INFO() << "PipelineEngine: stage2Parser messages size=" << messages.size(); if (messages.empty()) { return false; } for (auto& msg : messages) { if (!stage3Filter(msg)) { continue; } if (!stage4Validator(msg)) { continue; } (void)applyTransformAndEnrich(ctx, msg); } return true; } // 功能 :验证阶段4 // 参数 :ctx 数据 // 返回值 :是否成功 // 逻辑 :如果有效载荷无效 则返回false 如果都成功 则返回true bool PipelineEngine::stage4Validator(const softbus::core::models::DOMMessage& message) const { return !message.messageId.isEmpty(); } // 功能 :运行阶段2解析器 // 参数 :ctx 数据 // 返回值 :是否成功 // 逻辑 :如果插件管理器为空 则返回true 如果插件管理器不为空 则选择合适的插件 创建会话 如果会话为空 则返回false 如果会话不为空 则返回true std::vector PipelineEngine::stage2Parser(const softbus::core::models::RawBusMessage& ctx) { if (!m_pluginManager) { return {}; } auto parserPlugin = m_pluginManager->selectProtocolPlugin(ctx.protocolHint); if (!parserPlugin) { return {}; } const QString parserKey = ctx.endpoint + QStringLiteral("|") + parserPlugin->pluginId(); std::shared_ptr parserSession; { std::lock_guard lk(m_parserSessionMutex); auto it = m_parserSessions.find(parserKey); if (it == m_parserSessions.end() || !it.value()) { auto s = parserPlugin->createSession(); m_parserSessions.insert( parserKey, s ? std::shared_ptr(std::move(s)) : nullptr); it = m_parserSessions.find(parserKey); } if (it == m_parserSessions.end() || !it.value()) { return {}; } parserSession = it.value(); } softbus::message_bus::pipeline::protocol::ProtocolEnvelope envelope; // 协议封装 if (!parserSession->parse(ctx, envelope)) { return {}; } auto mapperPlugin = m_pluginManager->selectProtocolMapperPlugin(ctx.protocolHint); if (!mapperPlugin) { return {}; } const QString key = ctx.endpoint + QStringLiteral("|") + mapperPlugin->pluginId(); std::shared_ptr session; { std::lock_guard lk(m_mapperSessionMutex); auto it = m_mapperSessions.find(key); if (it == m_mapperSessions.end() || !it.value()) { auto s = mapperPlugin->createMapperSession(); m_mapperSessions.insert( key, s ? std::shared_ptr(std::move(s)) : nullptr); it = m_mapperSessions.find(key); } if (it == m_mapperSessions.end() || !it.value()) { return {}; } session = it.value(); } return session->map(ctx, envelope); } bool PipelineEngine::stage3Filter(softbus::core::models::DOMMessage& message) { static softbus::message_bus::pipeline::stages::filters::ProtocolParseFilter s_filter; return s_filter.process(message); } softbus::core::models::EnrichedMessage PipelineEngine::applyTransformAndEnrich( const softbus::core::models::RawBusMessage& rawCtx, softbus::core::models::DOMMessage& message) const { auto rules = softbus::message_bus::pipeline::DynamicRuleRegistry::instance().snapshotTransformRules( rawCtx.endpoint, rawCtx.deviceId, rawCtx.stableKey); for (const auto& rule : rules) { const double base = std::visit([](const auto& x) { return static_cast(x); }, message.value); const double next = base * rule.scale + rule.offset; if (next != base) { message.appendTrace(QStringLiteral("transform:%1 %2->%3") .arg(rule.id) .arg(base, 0, 'g', 12) .arg(next, 0, 'g', 12)); } message.value = next; if (!rule.unit.isEmpty()) { message.attributes.insert(QStringLiteral("unit"), rule.unit); } } static softbus::message_bus::pipeline::stages::filters::ProtocolParseFilter s_filter; return s_filter.enrich(message); } } // namespace softbus::message_bus::pipeline