user/include/app.hpp

341 lines
10 KiB
C++
Raw Permalink Normal View History

2026-07-09 02:02:27 +00:00
#ifndef DATAFLOW_APP_HPP
#define DATAFLOW_APP_HPP
#include <string>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <atomic>
#include <chrono>
#include <cstdint>
#include <stdexcept>
namespace dataflow {
/**
* @brief 线
*
* 线
*/
template<typename T>
class ThreadSafeQueue {
public:
ThreadSafeQueue() = default;
~ThreadSafeQueue() = default;
ThreadSafeQueue(const ThreadSafeQueue&) = delete;
ThreadSafeQueue& operator=(const ThreadSafeQueue&) = delete;
void push(T item) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push(std::move(item));
cond_.notify_one();
}
bool tryPop(T& item) {
std::lock_guard<std::mutex> lock(mutex_);
if (queue_.empty()) {
return false;
}
item = std::move(queue_.front());
queue_.pop();
return true;
}
void waitAndPop(T& item) {
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock, [this]() { return !queue_.empty(); });
item = std::move(queue_.front());
queue_.pop();
}
bool empty() const {
std::lock_guard<std::mutex> lock(mutex_);
return queue_.empty();
}
size_t size() const {
std::lock_guard<std::mutex> lock(mutex_);
return queue_.size();
}
void clear() {
std::lock_guard<std::mutex> lock(mutex_);
while (!queue_.empty()) {
queue_.pop();
}
}
private:
mutable std::mutex mutex_;
std::queue<T> queue_;
std::condition_variable cond_;
};
/**
* @brief
*
* TCP
* 4 + UTF-8
*/
struct RawDataPacket {
uint32_t length; ///< 消息体长度(字节数)
std::string body; ///< 消息体内容UTF-8 编码,最大 1024 字符)
};
/**
* @brief CSU-01
*
* TCP
* +
*
*/
class DataReceiver {
public:
/**
* @brief
* @param outputQueue
*/
explicit DataReceiver(ThreadSafeQueue<std::string>& outputQueue);
~DataReceiver();
/**
* @brief
*
* 线
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
* TCP
*/
void start();
/**
* @brief
*/
void stop();
/**
* @brief
* @param data
*
* 4 +
*/
void setMockDataSource(const std::vector<std::string>& data);
/** @brief 获取已成功接收并解析的数据包数量。 */
size_t getReceivedCount() const;
/** @brief 获取解析失败的数据包数量。 */
size_t getErrorCount() const;
/** @brief 获取最近一次错误信息。 */
std::string getLastError() const;
private:
/**
* @brief 线
*
* parsePacket
*
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
*
*/
void receiveLoop();
/**
* @brief
* @param buffer +
* @param offset /
* @param outData [out]
* @return true false
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
* +
*/
bool parsePacket(const std::vector<char>& buffer, size_t& offset, std::string& outData);
ThreadSafeQueue<std::string>& outputQueue_;
std::vector<std::string> mockData_;
std::atomic<bool> running_{false};
std::thread workerThread_;
std::atomic<size_t> receivedCount_{0};
std::atomic<size_t> errorCount_{0};
std::string lastError_;
mutable std::mutex errorMutex_;
};
/**
* @brief CSU-02
*
*
*
*
*/
class DataProcessor {
public:
/**
* @brief
* @param inputQueue CSU-01
* @param outputQueue CSU-03
*/
DataProcessor(ThreadSafeQueue<std::string>& inputQueue,
ThreadSafeQueue<std::string>& outputQueue);
~DataProcessor();
/**
* @brief
*
* 线
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
*
*/
void start();
/**
* @brief
*/
void stop();
/** @brief 获取成功处理的数据包数量。 */
size_t getProcessedCount() const;
/** @brief 因校验失败被丢弃的数据包数量。 */
size_t getDiscardedCount() const;
/** @brief 处理过程中发生异常的次数。 */
size_t getErrorCount() const;
/** @brief 获取最近一次错误信息。 */
std::string getLastError() const;
private:
/**
* @brief 线
*
* validateAndTransform
*
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
*
*/
void processLoop();
/**
* @brief
* @param rawData
* @param outProcessed [out]
* @return true false
*
*
* -
* - 1024
* - UTF-8 ASCII
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
*
*/
bool validateAndTransform(const std::string& rawData, std::string& outProcessed);
ThreadSafeQueue<std::string>& inputQueue_;
ThreadSafeQueue<std::string>& outputQueue_;
std::atomic<bool> running_{false};
std::thread workerThread_;
std::atomic<size_t> processedCount_{0};
std::atomic<size_t> discardedCount_{0};
std::atomic<size_t> errorCount_{0};
std::string lastError_;
mutable std::mutex errorMutex_;
};
/**
* @brief CSU-03
*
*
* 使 MySQL t_received_data
*/
class DataStorage {
public:
/**
* @brief
* @param inputQueue CSU-02
*/
explicit DataStorage(ThreadSafeQueue<std::string>& inputQueue);
~DataStorage();
/**
* @brief
*
* 线
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
*
*/
void start();
/**
* @brief
*/
void stop();
/** @brief 成功存储的数据条数。 */
size_t getStoredCount() const;
/** @brief 存储过程中发生的错误次数。 */
size_t getErrorCount() const;
/** @brief 获取最近一次错误信息。 */
std::string getLastError() const;
/**
* @brief
* @return
*/
std::vector<std::string> getAllStoredData() const;
/** @brief 当前存储的数据总条数。 */
size_t getStorageSize() const;
private:
/**
* @brief 线
*
* storeToDatabase
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
*
*/
void storageLoop();
/**
* @brief
* @param data
* @return true false
*
* @requirement(name="数据接收功能", id="SRS-测试_F-001")
*
*/
bool storeToDatabase(const std::string& data);
ThreadSafeQueue<std::string>& inputQueue_;
std::atomic<bool> running_{false};
std::thread workerThread_;
std::atomic<size_t> storedCount_{0};
std::atomic<size_t> errorCount_{0};
std::string lastError_;
mutable std::mutex errorMutex_;
/// 内存模拟数据库存储(对应 t_received_data 表的数据内容)
std::vector<std::string> storage_;
mutable std::mutex storageMutex_;
};
} // namespace dataflow
#endif // DATAFLOW_APP_HPP