常规更新

This commit is contained in:
2026-07-14 16:26:51 +08:00
parent 4697b2028a
commit 4fd18631d3
7 changed files with 1300 additions and 1453 deletions
+2 -2
View File
@@ -38,7 +38,7 @@
"function_name": "adsb_read" "function_name": "adsb_read"
}, },
"web_server": { "web_server": {
"webapp": "D:/ae/proj/projects/ECAP_Server/ver/v1.0.4/wwwroot", "webapp": "@/../third_party/eacp_webapp/wwwroot",
"tiles": "D:/tiles" "tiles": "D:/tiles"
}, },
"device": { "device": {
@@ -218,7 +218,7 @@
"mlat_server": true "mlat_server": true
}, },
"external_database": { "external_database": {
"ecap_sqlite_path": "D:/ae/proj/projects/ECAP_Server/sqlite/ecap.sqlite", "ecap_sqlite_path": "@/../data/sqlite/ecap.sqlite",
"list": [ "list": [
{ {
"name": "tar1090_db_aircraft", "name": "tar1090_db_aircraft",
@@ -1,16 +1,13 @@
#include "global.h" #include "global.h"
#include "../server/Global.h" #include "../server/Global.h"
#include "../server/Performance_Monitor.h" #include "../server/Performance_Monitor.h"
#include "Core/Base/Coro_Result.h" #include "Core/Base/Coro_Result.h"
#include "Resource_Utils.h" #include "Resource_Utils.h"
#include "Resources.h" #include "Resources.h"
#include <SQLiteCpp/Statement.h> #include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Transaction.h> #include <SQLiteCpp/Transaction.h>
#include <drogon/MultiPart.h> #include <drogon/MultiPart.h>
#include <trantor/utils/ConcurrentTaskQueue.h> #include <trantor/utils/ConcurrentTaskQueue.h>
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include <set> #include <set>
@@ -18,10 +15,9 @@
#include <utility> #include <utility>
#include <variant> #include <variant>
#include <string_view> #include <string_view>
namespace { namespace {
Psc::JSON Psc::JSON
external_resource_status_to_json(const External_Resource_Status &status) { external_resource_status_to_json(const External_Resource_Status& status) {
return Psc::JSON::object({ return Psc::JSON::object({
{"name", status.name}, {"name", status.name},
{"row_count", status.row_count}, {"row_count", status.row_count},
@@ -29,39 +25,35 @@ namespace {
{"imported", status.imported}, {"imported", status.imported},
{"message", status.message}, {"message", status.message},
}); });
} }
Psc::JSON external_resource_status_list_to_json(
Psc::JSON external_resource_status_list_to_json( const std::vector<External_Resource_Status>& status_list) {
const std::vector<External_Resource_Status> &status_list) {
auto result = Psc::JSON::array(); auto result = Psc::JSON::array();
for (const auto &status: status_list) { for (const auto& status : status_list) {
result.append(external_resource_status_to_json(status)); result.append(external_resource_status_to_json(status));
} }
return result; return result;
} }
trantor::ConcurrentTaskQueue& external_database_task_queue() {
trantor::ConcurrentTaskQueue &external_database_task_queue() {
static trantor::ConcurrentTaskQueue queue(2, "external_database"); static trantor::ConcurrentTaskQueue queue(2, "external_database");
return queue; return queue;
} }
template <typename T, typename Work, typename Callback>
template<typename T, typename Work, typename Callback> void run_external_database_async(Work&& work, Callback&& callback) {
void run_external_database_async(Work &&work, Callback &&callback) { auto callback_holder = std::make_shared<std::decay_t<Callback>>(
auto callback_holder = std::make_shared<std::decay_t<Callback> >(
std::forward<Callback>(callback)); std::forward<Callback>(callback));
external_database_task_queue().runTaskInQueue( external_database_task_queue().runTaskInQueue(
[work = std::forward<Work>(work), callback_holder]() mutable { [work = std::forward<Work>(work), callback_holder]() mutable {
try { try {
(*callback_holder)(nullptr, work()); (*callback_holder)(nullptr, work());
} catch (...) { }
catch (...) {
(*callback_holder)(std::current_exception(), T{}); (*callback_holder)(std::current_exception(), T{});
} }
}); });
} }
template <typename T, typename Starter>
template<typename T, typename Starter> asio::awaitable<T> await_external_database_callback(Starter starter) {
asio::awaitable<T> await_external_database_callback(Starter starter) {
auto result = co_await Psc::coro::callback_result<T>( auto result = co_await Psc::coro::callback_result<T>(
[starter = std::move(starter)](auto done) mutable { [starter = std::move(starter)](auto done) mutable {
starter([done = std::move(done)](std::exception_ptr exception, starter([done = std::move(done)](std::exception_ptr exception,
@@ -74,23 +66,20 @@ namespace {
}); });
}); });
co_return std::move(result); co_return std::move(result);
} }
} // namespace } // namespace
std::optional<std::string> std::optional<std::string>
External_Database_Row::get(std::string_view column) const { External_Database_Row::get(std::string_view column) const {
const auto iter = columns.find(std::string(column)); const auto iter = columns.find(std::string(column));
return iter == columns.end() ? std::nullopt : iter->second; return iter == columns.end() ? std::nullopt : iter->second;
} }
Psc::JSON External_Database_Row::to_json() const { Psc::JSON External_Database_Row::to_json() const {
auto result = Psc::JSON::object(); auto result = Psc::JSON::object();
for (const auto &[column, value]: columns) { for (const auto& [column, value] : columns) {
result.append({column, value ? Psc::JSON(*value) : Psc::JSON(nullptr)}); result.append({column, value ? Psc::JSON(*value) : Psc::JSON(nullptr)});
} }
return result; return result;
} }
External_Resources::External_Resources( External_Resources::External_Resources(
std::string_view name, std::string_view cache_file_name, std::string_view download_url, std::string_view name, std::string_view cache_file_name, std::string_view download_url,
std::string_view description, const std::uint64_t update_interval_seconds) { std::string_view description, const std::uint64_t update_interval_seconds) {
@@ -100,26 +89,23 @@ External_Resources::External_Resources(
this->description = std::string(description); this->description = std::string(description);
this->update_interval_seconds = update_interval_seconds; this->update_interval_seconds = update_interval_seconds;
} }
void External_Resources::mark_updated() { void External_Resources::mark_updated() {
last_updated_at = std::time(nullptr); last_updated_at = std::time(nullptr);
} }
void External_Resources::clear_last_updated_at() {
void External_Resources::clear_last_updated_at() { last_updated_at = 0; } last_updated_at = 0;
}
std::size_t External_Resources::row_count(SQLite::Database &db) const { std::size_t External_Resources::row_count(SQLite::Database& db) const {
return static_cast<std::size_t>( return static_cast<std::size_t>(
db.execAndGet("SELECT COUNT(*) FROM " + db.execAndGet("SELECT COUNT(*) FROM " +
External_Database_Utils::quote_identifier(name)) External_Database_Utils::quote_identifier(name))
.getInt64()); .getInt64());
} }
std::filesystem::path std::filesystem::path
External_Resources::source_file(const std::filesystem::path &cache_pos) const { External_Resources::source_file(const std::filesystem::path& cache_pos) const {
return cache_pos / cache_file_name; return cache_pos / cache_file_name;
} }
bool External_Resources::fetch(const std::filesystem::path& cache_pos,
bool External_Resources::fetch(const std::filesystem::path &cache_pos,
const bool force_download) const { const bool force_download) const {
const auto target_file = source_file(cache_pos); const auto target_file = source_file(cache_pos);
if (!force_download) if (!force_download)
@@ -129,8 +115,7 @@ bool External_Resources::fetch(const std::filesystem::path &cache_pos,
External_Database_Utils::download_to_file(download_url, target_file); External_Database_Utils::download_to_file(download_url, target_file);
return true; return true;
} }
External_Resource_Status External_Resources::update(SQLite::Database& db, const std::filesystem::path& cache_pos,
External_Resource_Status External_Resources::update(SQLite::Database &db, const std::filesystem::path &cache_pos,
const bool force_download, const bool only_when_empty) { const bool force_download, const bool only_when_empty) {
create_table(db); create_table(db);
External_Resource_Status result{name, row_count(db), false, false, ""}; External_Resource_Status result{name, row_count(db), false, false, ""};
@@ -154,17 +139,15 @@ External_Resource_Status External_Resources::update(SQLite::Database &db, const
: "cache file unavailable"; : "cache file unavailable";
return result; return result;
} }
result.row_count = import_file(db, local_file); result.row_count = import_file(db, local_file);
result.imported = true; result.imported = true;
result.message = "ok"; result.message = "ok";
mark_updated(); mark_updated();
return result; return result;
} }
External_Resource_Status External_Resource_Status
External_Resources::import_offline(SQLite::Database &db, External_Resources::import_offline(SQLite::Database& db,
const std::filesystem::path &source_file) { const std::filesystem::path& source_file) {
create_table(db); create_table(db);
External_Resource_Status result{name, 0, false, false, ""}; External_Resource_Status result{name, 0, false, false, ""};
result.row_count = import_file(db, source_file); result.row_count = import_file(db, source_file);
@@ -173,16 +156,14 @@ External_Resources::import_offline(SQLite::Database &db,
mark_updated(); mark_updated();
return result; return result;
} }
External_Resource_Status External_Resource_Status
External_Resources::clear_table(SQLite::Database &db, External_Resources::clear_table(SQLite::Database& db,
const std::filesystem::path &cache_pos) { const std::filesystem::path& cache_pos) {
SQLite::Transaction transaction(db); SQLite::Transaction transaction(db);
db.exec("DROP TABLE IF EXISTS " + db.exec("DROP TABLE IF EXISTS " +
External_Database_Utils::quote_identifier(name)); External_Database_Utils::quote_identifier(name));
create_table(db); create_table(db);
transaction.commit(); transaction.commit();
if (!cache_file_name.empty()) { if (!cache_file_name.empty()) {
std::error_code error; std::error_code error;
std::filesystem::remove(source_file(cache_pos), error); std::filesystem::remove(source_file(cache_pos), error);
@@ -191,20 +172,17 @@ External_Resources::clear_table(SQLite::Database &db,
": " + error.message()); ": " + error.message());
} }
} }
clear_last_updated_at(); clear_last_updated_at();
return {name, 0, false, false, "table cleared"}; return {name, 0, false, false, "table cleared"};
} }
std::optional<External_Database_Row> External_Resources::query_one( std::optional<External_Database_Row> External_Resources::query_one(
SQLite::Database &db, SQLite::Database& db,
const std::vector<std::string> &primary_key_values) const { const std::vector<std::string>& primary_key_values) const {
const auto &columns = primary_key_columns(); const auto& columns = primary_key_columns();
if (columns.size() != primary_key_values.size()) { if (columns.size() != primary_key_values.size()) {
throw std::invalid_argument( throw std::invalid_argument(
"primary key value count mismatch for resource: " + name); "primary key value count mismatch for resource: " + name);
} }
std::string sql = "SELECT * FROM " + std::string sql = "SELECT * FROM " +
External_Database_Utils::quote_identifier(name) + " WHERE "; External_Database_Utils::quote_identifier(name) + " WHERE ";
for (std::size_t index = 0; index < columns.size(); ++index) { for (std::size_t index = 0; index < columns.size(); ++index) {
@@ -214,7 +192,6 @@ std::optional<External_Database_Row> External_Resources::query_one(
" = ? COLLATE NOCASE"; " = ? COLLATE NOCASE";
} }
sql += " LIMIT 1"; sql += " LIMIT 1";
SQLite::Statement statement(db, sql); SQLite::Statement statement(db, sql);
for (std::size_t index = 0; index < primary_key_values.size(); ++index) { for (std::size_t index = 0; index < primary_key_values.size(); ++index) {
statement.bind( statement.bind(
@@ -223,19 +200,18 @@ std::optional<External_Database_Row> External_Resources::query_one(
} }
if (!statement.executeStep()) if (!statement.executeStep())
return std::nullopt; return std::nullopt;
External_Database_Row row; External_Database_Row row;
for (int index = 0; index < statement.getColumnCount(); ++index) { for (int index = 0; index < statement.getColumnCount(); ++index) {
const auto name = statement.getColumnName(index); const auto name = statement.getColumnName(index);
if (statement.isColumnNull(index)) { if (statement.isColumnNull(index)) {
row.columns.emplace(name, std::nullopt); row.columns.emplace(name, std::nullopt);
} else { }
else {
row.columns.emplace(name, statement.getColumn(index).getString()); row.columns.emplace(name, statement.getColumn(index).getString());
} }
} }
return row; return row;
} }
External_Resources_Manager::External_Resources_Manager() { External_Resources_Manager::External_Resources_Manager() {
register_external_resource(make_tar1090_db_aircraft_csv_gz_resource()); register_external_resource(make_tar1090_db_aircraft_csv_gz_resource());
register_external_resource(make_wiedehopf_tar1090_db_resource()); register_external_resource(make_wiedehopf_tar1090_db_resource());
@@ -249,19 +225,18 @@ External_Resources_Manager::External_Resources_Manager() {
register_external_resource(make_vradarserver_standing_data_resource()); register_external_resource(make_vradarserver_standing_data_resource());
register_external_resource(make_opensky_flightdata_api_resource()); register_external_resource(make_opensky_flightdata_api_resource());
} }
void External_Resources_Manager::init(const Psc::JSON* that_json) {
void External_Resources_Manager::init(const Psc::JSON *that_json) {
if (!that_json) if (!that_json)
return; return;
const auto list = that_json->get("list"); const auto list = that_json->get("list");
if (!list) if (!list)
return; return;
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
for (const auto &config: list->children) { for (const auto& config : list->children) {
const auto name = config.try_get_string("name"); const auto name = config.try_get_string("name");
if (!name) if (!name)
continue; continue;
for (const auto &resource: resources_) { for (const auto& resource : resources_) {
if (resource->name != *name) if (resource->name != *name)
continue; continue;
resource->init(&config); resource->init(&config);
@@ -270,27 +245,25 @@ void External_Resources_Manager::init(const Psc::JSON *that_json) {
} }
Get_J(ecap_sqlite_path) Get_J(ecap_sqlite_path)
} }
Psc::JSON External_Resources_Manager::to_base_json() const { Psc::JSON External_Resources_Manager::to_base_json() const {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
auto ret = Psc::JSON::object(); auto ret = Psc::JSON::object();
Ret_J(ecap_sqlite_path) Ret_J(ecap_sqlite_path)
auto list = Psc::JSON::array(); auto list = Psc::JSON::array();
for (const std::unique_ptr<External_Resources> &resource: resources_) { for (const std::unique_ptr<External_Resources>& resource : resources_) {
list.children.emplace_back(resource->to_json()); list.children.emplace_back(resource->to_json());
} }
ret.children.emplace_back(Psc::JSON{"list", list}); ret.children.emplace_back(Psc::JSON{"list", list});
return ret; return ret;
} }
void External_Resources_Manager::load_sqlite_db(std::string_view path) { void External_Resources_Manager::load_sqlite_db(std::string_view path) {
try { try {
db_ = std::make_unique<SQLite::Database>(path, SQLite::OPEN_READWRITE | db_ = std::make_unique<SQLite::Database>(path, SQLite::OPEN_READWRITE |
SQLite::OPEN_CREATE); SQLite::OPEN_CREATE);
} catch (SQLite::Exception &error) { }
catch (SQLite::Exception& error) {
Psc::fail_fast(std::string("load_sqlite_db error: ") + error.what()); Psc::fail_fast(std::string("load_sqlite_db error: ") + error.what());
} }
db_->exec("PRAGMA journal_mode=WAL;"); db_->exec("PRAGMA journal_mode=WAL;");
db_->exec("PRAGMA synchronous=NORMAL;"); db_->exec("PRAGMA synchronous=NORMAL;");
auto pos = std::filesystem::path(path).parent_path(); auto pos = std::filesystem::path(path).parent_path();
@@ -298,63 +271,53 @@ void External_Resources_Manager::load_sqlite_db(std::string_view path) {
initialize(*db_, pos); initialize(*db_, pos);
sync_missing(*db_); sync_missing(*db_);
} }
std::vector<External_Resource_Status> std::vector<External_Resource_Status>
External_Resources_Manager::refresh_external_databases( External_Resources_Manager::refresh_external_databases(
const bool force_download) { const bool force_download) {
return refresh_all(require_db(), force_download); return refresh_all(require_db(), force_download);
} }
External_Resource_Status External_Resources_Manager::refresh_external_database( External_Resource_Status External_Resources_Manager::refresh_external_database(
std::string_view resource_name, const bool force_download) { std::string_view resource_name, const bool force_download) {
return refresh_one(require_db(), resource_name, force_download); return refresh_one(require_db(), resource_name, force_download);
} }
External_Resource_Status External_Resources_Manager::import_external_database( External_Resource_Status External_Resources_Manager::import_external_database(
std::string_view resource_name, std::string_view resource_name,
const std::filesystem::path &source_file) { const std::filesystem::path& source_file) {
return import_offline(require_db(), resource_name, source_file); return import_offline(require_db(), resource_name, source_file);
} }
External_Resource_Status External_Resource_Status
External_Resources_Manager::clear_external_database_table( External_Resources_Manager::clear_external_database_table(
std::string_view resource_name) { std::string_view resource_name) {
return clear_table(require_db(), resource_name); return clear_table(require_db(), resource_name);
} }
std::optional<External_Database_Row> std::optional<External_Database_Row>
External_Resources_Manager::query_external_database( External_Resources_Manager::query_external_database(
std::string_view resource_name, std::string_view resource_name,
const std::vector<std::string> &primary_key_values) const { const std::vector<std::string>& primary_key_values) const {
return query_one(require_db(), resource_name, primary_key_values); return query_one(require_db(), resource_name, primary_key_values);
} }
std::map<std::string, std::shared_ptr<External_Database_Row>>
std::map<std::string, std::shared_ptr<External_Database_Row> >
External_Resources_Manager::query_aircraft_external_databases( External_Resources_Manager::query_aircraft_external_databases(
std::string_view icao24) const { std::string_view icao24) const {
return query_aircraft(require_db(), icao24); return query_aircraft(require_db(), icao24);
} }
std::map<std::string, std::shared_ptr<External_Database_Row>>
std::map<std::string, std::shared_ptr<External_Database_Row> >
External_Resources_Manager::query_callsign_external_databases( External_Resources_Manager::query_callsign_external_databases(
const std::optional<std::string> &callsign) const { const std::optional<std::string>& callsign) const {
return query_callsign(require_db(), callsign); return query_callsign(require_db(), callsign);
} }
std::vector<External_Resource_Status> std::vector<External_Resource_Status>
External_Resources_Manager::external_database_status() const { External_Resources_Manager::external_database_status() const {
return status(require_db()); return status(require_db());
} }
void External_Resources_Manager::async_refresh_external_databases( void External_Resources_Manager::async_refresh_external_databases(
const bool force_download, Status_List_Callback callback) { const bool force_download, Status_List_Callback callback) {
run_external_database_async<std::vector<External_Resource_Status> >( run_external_database_async<std::vector<External_Resource_Status>>(
[this, force_download]() { [this, force_download]() {
return refresh_external_databases(force_download); return refresh_external_databases(force_download);
}, },
std::move(callback)); std::move(callback));
} }
void External_Resources_Manager::async_refresh_external_database( void External_Resources_Manager::async_refresh_external_database(
std::string_view resource_name, const bool force_download, std::string_view resource_name, const bool force_download,
Status_Callback callback) { Status_Callback callback) {
@@ -364,7 +327,6 @@ void External_Resources_Manager::async_refresh_external_database(
}, },
std::move(callback)); std::move(callback));
} }
void External_Resources_Manager::async_import_external_database( void External_Resources_Manager::async_import_external_database(
std::string_view resource_name, std::filesystem::path source_file, std::string_view resource_name, std::filesystem::path source_file,
Status_Callback callback) { Status_Callback callback) {
@@ -375,7 +337,6 @@ void External_Resources_Manager::async_import_external_database(
}, },
std::move(callback)); std::move(callback));
} }
void External_Resources_Manager::async_clear_external_database_table( void External_Resources_Manager::async_clear_external_database_table(
std::string_view resource_name, Status_Callback callback) { std::string_view resource_name, Status_Callback callback) {
run_external_database_async<External_Resource_Status>( run_external_database_async<External_Resource_Status>(
@@ -384,54 +345,50 @@ void External_Resources_Manager::async_clear_external_database_table(
}, },
std::move(callback)); std::move(callback));
} }
void External_Resources_Manager::async_query_external_database( void External_Resources_Manager::async_query_external_database(
std::string_view resource_name, std::vector<std::string> primary_key_values, std::string_view resource_name, std::vector<std::string> primary_key_values,
Row_Callback callback) const { Row_Callback callback) const {
run_external_database_async<std::optional<External_Database_Row> >( run_external_database_async<std::optional<External_Database_Row>>(
[this, resource_name = std::move(resource_name), [this, resource_name = std::move(resource_name),
primary_key_values = std::move(primary_key_values)]() { primary_key_values = std::move(primary_key_values)]() {
return query_external_database(resource_name, primary_key_values); return query_external_database(resource_name, primary_key_values);
}, },
std::move(callback)); std::move(callback));
} }
void External_Resources_Manager::async_query_aircraft_external_databases( void External_Resources_Manager::async_query_aircraft_external_databases(
std::string_view icao24, Row_Map_Callback callback) const { std::string_view icao24, Row_Map_Callback callback) const {
run_external_database_async< run_external_database_async<
std::map<std::string, std::shared_ptr<External_Database_Row> > >( std::map<std::string, std::shared_ptr<External_Database_Row>>>(
[this, icao24 = std::move(icao24)]() { [this, icao24 = std::move(icao24)]() {
return query_aircraft_external_databases(icao24); return query_aircraft_external_databases(icao24);
}, },
std::move(callback)); std::move(callback));
} }
void External_Resources_Manager::async_query_callsign_external_databases( void External_Resources_Manager::async_query_callsign_external_databases(
std::optional<std::string> callsign, Row_Map_Callback callback) const { std::optional<std::string> callsign, Row_Map_Callback callback) const {
run_external_database_async< run_external_database_async<
std::map<std::string, std::shared_ptr<External_Database_Row> > >( std::map<std::string, std::shared_ptr<External_Database_Row>>>(
[this, callsign = std::move(callsign)]() { [this, callsign = std::move(callsign)]() {
return query_callsign_external_databases(callsign); return query_callsign_external_databases(callsign);
}, },
std::move(callback)); std::move(callback));
} }
void External_Resources_Manager::async_external_database_status( void External_Resources_Manager::async_external_database_status(
Status_List_Callback callback) const { Status_List_Callback callback) const {
run_external_database_async<std::vector<External_Resource_Status> >( run_external_database_async<std::vector<External_Resource_Status>>(
[this]() { return external_database_status(); }, std::move(callback)); [this]() {
return external_database_status();
}, std::move(callback));
} }
asio::awaitable<std::vector<External_Resource_Status>>
asio::awaitable<std::vector<External_Resource_Status> >
External_Resources_Manager::refresh_external_databases_coro( External_Resources_Manager::refresh_external_databases_coro(
const bool force_download) { const bool force_download) {
co_return co_await await_external_database_callback< co_return co_await await_external_database_callback<
std::vector<External_Resource_Status> >( std::vector<External_Resource_Status>>(
[this, force_download](Status_List_Callback callback) { [this, force_download](Status_List_Callback callback) {
async_refresh_external_databases(force_download, std::move(callback)); async_refresh_external_databases(force_download, std::move(callback));
}); });
} }
asio::awaitable<External_Resource_Status> asio::awaitable<External_Resource_Status>
External_Resources_Manager::refresh_external_database_coro( External_Resources_Manager::refresh_external_database_coro(
std::string_view resource_name, const bool force_download) { std::string_view resource_name, const bool force_download) {
@@ -442,7 +399,6 @@ External_Resources_Manager::refresh_external_database_coro(
force_download, std::move(callback)); force_download, std::move(callback));
}); });
} }
asio::awaitable<External_Resource_Status> asio::awaitable<External_Resource_Status>
External_Resources_Manager::import_external_database_coro( External_Resources_Manager::import_external_database_coro(
std::string_view resource_name, std::filesystem::path source_file) { std::string_view resource_name, std::filesystem::path source_file) {
@@ -454,7 +410,6 @@ External_Resources_Manager::import_external_database_coro(
std::move(callback)); std::move(callback));
}); });
} }
asio::awaitable<External_Resource_Status> asio::awaitable<External_Resource_Status>
External_Resources_Manager::clear_external_database_table_coro( External_Resources_Manager::clear_external_database_table_coro(
std::string_view resource_name) { std::string_view resource_name) {
@@ -465,13 +420,12 @@ External_Resources_Manager::clear_external_database_table_coro(
std::move(callback)); std::move(callback));
}); });
} }
asio::awaitable<std::optional<External_Database_Row>>
asio::awaitable<std::optional<External_Database_Row> >
External_Resources_Manager::query_external_database_coro( External_Resources_Manager::query_external_database_coro(
std::string_view resource_name, std::string_view resource_name,
std::vector<std::string> primary_key_values) const { std::vector<std::string> primary_key_values) const {
co_return co_await await_external_database_callback< co_return co_await await_external_database_callback<
std::optional<External_Database_Row> >( std::optional<External_Database_Row>>(
[this, resource_name = std::move(resource_name), [this, resource_name = std::move(resource_name),
primary_key_values = primary_key_values =
std::move(primary_key_values)](Row_Callback callback) mutable { std::move(primary_key_values)](Row_Callback callback) mutable {
@@ -480,12 +434,11 @@ External_Resources_Manager::query_external_database_coro(
std::move(callback)); std::move(callback));
}); });
} }
asio::awaitable<std::shared_ptr<External_Database_Row_Map>>
asio::awaitable<std::shared_ptr<External_Database_Row_Map> >
External_Resources_Manager::query_aircraft_external_databases_coro( External_Resources_Manager::query_aircraft_external_databases_coro(
std::string_view icao24) const { std::string_view icao24) const {
auto result = co_await Psc::coro::callback_result< auto result = co_await Psc::coro::callback_result<
std::shared_ptr<External_Database_Row_Map> >( std::shared_ptr<External_Database_Row_Map>>(
[this, icao24 = std::move(icao24)](auto done) mutable { [this, icao24 = std::move(icao24)](auto done) mutable {
async_query_aircraft_external_databases( async_query_aircraft_external_databases(
std::move(icao24), std::move(icao24),
@@ -501,12 +454,11 @@ External_Resources_Manager::query_aircraft_external_databases_coro(
}); });
co_return result; co_return result;
} }
asio::awaitable<std::shared_ptr<External_Database_Row_Map>>
asio::awaitable<std::shared_ptr<External_Database_Row_Map> >
External_Resources_Manager::query_callsign_external_databases_coro( External_Resources_Manager::query_callsign_external_databases_coro(
std::optional<std::string> callsign) const { std::optional<std::string> callsign) const {
auto result = co_await Psc::coro::callback_result< auto result = co_await Psc::coro::callback_result<
std::shared_ptr<External_Database_Row_Map> >( std::shared_ptr<External_Database_Row_Map>>(
[this, callsign = std::move(callsign)](auto done) mutable { [this, callsign = std::move(callsign)](auto done) mutable {
async_query_callsign_external_databases( async_query_callsign_external_databases(
std::move(callsign), std::move(callsign),
@@ -522,36 +474,31 @@ External_Resources_Manager::query_callsign_external_databases_coro(
}); });
co_return result; co_return result;
} }
asio::awaitable<std::vector<External_Resource_Status>>
asio::awaitable<std::vector<External_Resource_Status> >
External_Resources_Manager::external_database_status_coro() const { External_Resources_Manager::external_database_status_coro() const {
co_return co_await await_external_database_callback< co_return co_await await_external_database_callback<
std::vector<External_Resource_Status> >( std::vector<External_Resource_Status>>(
[this](Status_List_Callback callback) { [this](Status_List_Callback callback) {
async_external_database_status(std::move(callback)); async_external_database_status(std::move(callback));
}); });
} }
void External_Resources_Manager::server(Global* g) {
void External_Resources_Manager::server(Global *g) { auto& svr = g->svr;
auto &svr = g->svr; const auto& api = g->api;
const auto &api = g->api;
svr.Post(api + "get_external_database_config", [this](HTTP_Param) { svr.Post(api + "get_external_database_config", [this](HTTP_Param) {
auto t = warp(to_base_json()).to_json_string(); auto t = warp(to_base_json()).to_json_string();
res->setBody(t); res->setBody(t);
}); });
svr.PostCoro( svr.Post_Coro(
api + "get_external_database_status", api + "get_external_database_status",
[this](HTTP_Param) -> drogon::Task<> { [this](HTTP_Param) -> drogon::Task<> {
auto status_list = auto status_list =
co_await Ecap_Coro::to_drogon(external_database_status_coro()); co_await Ecap_Coro::to_drogon(external_database_status_coro());
res->setBody(warp(external_resource_status_list_to_json(status_list)) res->setBody(warp(external_resource_status_list_to_json(status_list))
.to_json_string()); .to_json_string());
co_return; co_return;
}); });
svr.PostCoro( svr.Post_Coro(
api + "refresh_external_database", api + "refresh_external_database",
[this, g](HTTP_Param) -> drogon::Task<> { [this, g](HTTP_Param) -> drogon::Task<> {
CHECK_JSON_PARAM CHECK_JSON_PARAM
@@ -563,7 +510,7 @@ void External_Resources_Manager::server(Global *g) {
warp(external_resource_status_to_json(result)).to_json_string()); warp(external_resource_status_to_json(result)).to_json_string());
co_return; co_return;
}); });
svr.PostCoro(api + "refresh_external_databases", svr.Post_Coro(api + "refresh_external_databases",
[this, g](HTTP_Param) -> drogon::Task<> { [this, g](HTTP_Param) -> drogon::Task<> {
const auto result = co_await Ecap_Coro::to_drogon( const auto result = co_await Ecap_Coro::to_drogon(
refresh_external_databases_coro(true)); refresh_external_databases_coro(true));
@@ -573,7 +520,7 @@ void External_Resources_Manager::server(Global *g) {
.to_json_string()); .to_json_string());
co_return; co_return;
}); });
svr.PostCoro( svr.Post_Coro(
api + "import_external_database", api + "import_external_database",
[this, g](HTTP_Param) -> drogon::Task<> { [this, g](HTTP_Param) -> drogon::Task<> {
CHECK_JSON_PARAM CHECK_JSON_PARAM
@@ -586,7 +533,7 @@ void External_Resources_Manager::server(Global *g) {
warp(external_resource_status_to_json(result)).to_json_string()); warp(external_resource_status_to_json(result)).to_json_string());
co_return; co_return;
}); });
svr.PostCoro( svr.Post_Coro(
api + "upload_external_database", api + "upload_external_database",
[this, g](HTTP_Param) -> drogon::Task<> { [this, g](HTTP_Param) -> drogon::Task<> {
drogon::MultiPartParser parser; drogon::MultiPartParser parser;
@@ -597,8 +544,7 @@ void External_Resources_Manager::server(Global *g) {
if (!name || parser.getFiles().size() != 1) { if (!name || parser.getFiles().size() != 1) {
throw_invalid_http_param("name or file"); throw_invalid_http_param("name or file");
} }
const auto& upload = parser.getFiles().front();
const auto &upload = parser.getFiles().front();
const auto serial = const auto serial =
std::chrono::steady_clock::now().time_since_epoch().count(); std::chrono::steady_clock::now().time_since_epoch().count();
auto extension = std::string(upload.getFileExtension()); auto extension = std::string(upload.getFileExtension());
@@ -611,7 +557,6 @@ void External_Resources_Manager::server(Global *g) {
throw std::runtime_error( throw std::runtime_error(
"Cannot save uploaded external database file"); "Cannot save uploaded external database file");
} }
const auto source_file = const auto source_file =
std::filesystem::path(drogon::app().getUploadPath()) / saved_name; std::filesystem::path(drogon::app().getUploadPath()) / saved_name;
const auto result = co_await Ecap_Coro::to_drogon( const auto result = co_await Ecap_Coro::to_drogon(
@@ -621,7 +566,7 @@ void External_Resources_Manager::server(Global *g) {
warp(external_resource_status_to_json(result)).to_json_string()); warp(external_resource_status_to_json(result)).to_json_string());
co_return; co_return;
}); });
svr.PostCoro( svr.Post_Coro(
api + "clear_external_database_table", api + "clear_external_database_table",
[this, g](HTTP_Param) -> drogon::Task<> { [this, g](HTTP_Param) -> drogon::Task<> {
CHECK_JSON_PARAM CHECK_JSON_PARAM
@@ -633,14 +578,14 @@ void External_Resources_Manager::server(Global *g) {
warp(external_resource_status_to_json(result)).to_json_string()); warp(external_resource_status_to_json(result)).to_json_string());
co_return; co_return;
}); });
svr.PostCoro( svr.Post_Coro(
api + "query_external_database", [this](HTTP_Param) -> drogon::Task<> { api + "query_external_database", [this](HTTP_Param) -> drogon::Task<> {
CHECK_JSON_PARAM CHECK_JSON_PARAM
HTTP_REQUIRE_VALUE(name, params.try_get_string("name")) HTTP_REQUIRE_VALUE(name, params.try_get_string("name"))
HTTP_REQUIRE_PTR(primary_key_values_json, HTTP_REQUIRE_PTR(primary_key_values_json,
params.get("primary_key_values")) params.get("primary_key_values"))
std::vector<std::string> primary_key_values; std::vector<std::string> primary_key_values;
for (const auto &value: primary_key_values_json->children) { for (const auto& value : primary_key_values_json->children) {
if (value.valueType != Psc::JsonType::String) { if (value.valueType != Psc::JsonType::String) {
throw_invalid_http_param("primary_key_values"); throw_invalid_http_param("primary_key_values");
} }
@@ -654,65 +599,56 @@ void External_Resources_Manager::server(Global *g) {
co_return; co_return;
}); });
} }
void External_Resources_Manager::register_external_resource( void External_Resources_Manager::register_external_resource(
std::unique_ptr<External_Resources> external_res) { std::unique_ptr<External_Resources> external_res) {
if (!external_res) if (!external_res)
throw std::invalid_argument("external resource is null"); throw std::invalid_argument("external resource is null");
resources_.push_back(std::move(external_res)); resources_.push_back(std::move(external_res));
} }
void External_Resources_Manager::initialize(SQLite::Database& db,
void External_Resources_Manager::initialize(SQLite::Database &db,
std::filesystem::path cache_pos) { std::filesystem::path cache_pos) {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
cache_pos_ = std::move(cache_pos); cache_pos_ = std::move(cache_pos);
for (const auto &resource: resources_) for (const auto& resource : resources_)
resource->create_table(db); resource->create_table(db);
} }
std::vector<External_Resource_Status> std::vector<External_Resource_Status>
External_Resources_Manager::sync_missing(SQLite::Database &db) { External_Resources_Manager::sync_missing(SQLite::Database& db) {
return update_all(db, false, true); return update_all(db, false, true);
} }
std::vector<External_Resource_Status> std::vector<External_Resource_Status>
External_Resources_Manager::refresh_all(SQLite::Database &db, External_Resources_Manager::refresh_all(SQLite::Database& db,
const bool force_download) { const bool force_download) {
return update_all(db, force_download, false); return update_all(db, force_download, false);
} }
External_Resource_Status External_Resource_Status
External_Resources_Manager::refresh_one(SQLite::Database &db, External_Resources_Manager::refresh_one(SQLite::Database& db,
std::string_view resource_name, std::string_view resource_name,
const bool force_download) { const bool force_download) {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
return get_resource(resource_name) return get_resource(resource_name)
.update(db, cache_pos_, force_download, false); .update(db, cache_pos_, force_download, false);
} }
External_Resource_Status External_Resources_Manager::import_offline( External_Resource_Status External_Resources_Manager::import_offline(
SQLite::Database &db, std::string_view resource_name, SQLite::Database& db, std::string_view resource_name,
const std::filesystem::path &source_file) { const std::filesystem::path& source_file) {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
return get_resource(resource_name).import_offline(db, source_file); return get_resource(resource_name).import_offline(db, source_file);
} }
External_Resource_Status External_Resource_Status
External_Resources_Manager::clear_table(SQLite::Database &db, External_Resources_Manager::clear_table(SQLite::Database& db,
std::string_view resource_name) { std::string_view resource_name) {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
return get_resource(resource_name).clear_table(db, cache_pos_); return get_resource(resource_name).clear_table(db, cache_pos_);
} }
std::optional<External_Database_Row> External_Resources_Manager::query_one( std::optional<External_Database_Row> External_Resources_Manager::query_one(
SQLite::Database &db, std::string_view resource_name, SQLite::Database& db, std::string_view resource_name,
const std::vector<std::string> &primary_key_values) const { const std::vector<std::string>& primary_key_values) const {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
return get_resource(resource_name).query_one(db, primary_key_values); return get_resource(resource_name).query_one(db, primary_key_values);
} }
std::map<std::string, std::shared_ptr<External_Database_Row>>
std::map<std::string, std::shared_ptr<External_Database_Row> > External_Resources_Manager::query_aircraft(SQLite::Database& db,
External_Resources_Manager::query_aircraft(SQLite::Database &db,
std::string_view icao24) const { std::string_view icao24) const {
Scope_Timer timer( Scope_Timer timer(
"external_database.query_aircraft", "external_database.query_aircraft",
@@ -723,11 +659,11 @@ External_Resources_Manager::query_aircraft(SQLite::Database &db,
"faa_aircraft_registry", "faa_aircraft_registry",
}; };
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
std::map<std::string, std::shared_ptr<External_Database_Row> > result; std::map<std::string, std::shared_ptr<External_Database_Row>> result;
const auto add_row = [&](std::string_view resource_name, const auto add_row = [&](std::string_view resource_name,
const std::vector<std::string> &primary_key_values, const std::vector<std::string>& primary_key_values,
std::string_view result_name = std::string{}) { std::string_view result_name = std::string{}) {
auto &resource = get_resource(resource_name); auto& resource = get_resource(resource_name);
auto row = resource.query_one(db, primary_key_values); auto row = resource.query_one(db, primary_key_values);
if (!row) if (!row)
return std::shared_ptr<External_Database_Row>{}; return std::shared_ptr<External_Database_Row>{};
@@ -736,9 +672,8 @@ External_Resources_Manager::query_aircraft(SQLite::Database &db,
shared_row); shared_row);
return shared_row; return shared_row;
}; };
std::optional<std::string> type_code; std::optional<std::string> type_code;
for (const auto &resource_name: kAircraftResourceKeys) { for (const auto& resource_name : kAircraftResourceKeys) {
const auto row = add_row(resource_name, std::vector<std::string>{std::string(icao24)}); const auto row = add_row(resource_name, std::vector<std::string>{std::string(icao24)});
if (row && !type_code) { if (row && !type_code) {
type_code = row->get("type_code"); type_code = row->get("type_code");
@@ -746,15 +681,13 @@ External_Resources_Manager::query_aircraft(SQLite::Database &db,
type_code = row->get("typecode"); type_code = row->get("typecode");
} }
} }
if (type_code) if (type_code)
add_row("icao_doc_8643_aircraft_type_designators", {*type_code}); add_row("icao_doc_8643_aircraft_type_designators", {*type_code});
return result; return result;
} }
std::map<std::string, std::shared_ptr<External_Database_Row>>
std::map<std::string, std::shared_ptr<External_Database_Row> >
External_Resources_Manager::query_callsign( External_Resources_Manager::query_callsign(
SQLite::Database &db, const std::optional<std::string> &callsign) const { SQLite::Database& db, const std::optional<std::string>& callsign) const {
Scope_Timer timer( Scope_Timer timer(
"external_database.query_callsign", "external_database.query_callsign",
Global::instance()->http_monitor_config.slow_scope_threshold_ms); Global::instance()->http_monitor_config.slow_scope_threshold_ms);
@@ -763,13 +696,12 @@ External_Resources_Manager::query_callsign(
"adsblol_vrs_standing_data_routes", "adsblol_vrs_standing_data_routes",
"vradarserver_standing_data_routes", "vradarserver_standing_data_routes",
}; };
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
std::map<std::string, std::shared_ptr<External_Database_Row> > result; std::map<std::string, std::shared_ptr<External_Database_Row>> result;
const auto add_row = [&](std::string_view resource_name, const auto add_row = [&](std::string_view resource_name,
const std::vector<std::string> &primary_key_values, const std::vector<std::string>& primary_key_values,
std::string_view result_name = std::string{}) { std::string_view result_name = std::string{}) {
auto &resource = get_resource(resource_name); auto& resource = get_resource(resource_name);
auto row = resource.query_one(db, primary_key_values); auto row = resource.query_one(db, primary_key_values);
if (!row) if (!row)
return std::shared_ptr<External_Database_Row>{}; return std::shared_ptr<External_Database_Row>{};
@@ -778,17 +710,15 @@ External_Resources_Manager::query_callsign(
shared_row); shared_row);
return shared_row; return shared_row;
}; };
std::set<std::string> airport_codes; std::set<std::string> airport_codes;
if (callsign && !callsign->empty()) { if (callsign && !callsign->empty()) {
for (const auto &resource_name: kRouteResourceKeys) { for (const auto& resource_name : kRouteResourceKeys) {
const auto row = add_row(resource_name, {*callsign}); const auto row = add_row(resource_name, {*callsign});
if (!row) if (!row)
continue; continue;
const auto airports = row->get("AirportCodes"); const auto airports = row->get("AirportCodes");
if (!airports) if (!airports)
continue; continue;
std::size_t start = 0; std::size_t start = 0;
while (start < airports->size()) { while (start < airports->size()) {
const auto end = airports->find('-', start); const auto end = airports->find('-', start);
@@ -799,49 +729,44 @@ External_Resources_Manager::query_callsign(
} }
} }
} }
for (const auto& airport_code : airport_codes) {
for (const auto &airport_code: airport_codes) {
if (airport_code.empty()) if (airport_code.empty())
continue; continue;
add_row("vrs_airports", {airport_code}, "vrs_airports:" + airport_code); add_row("vrs_airports", {airport_code}, "vrs_airports:" + airport_code);
} }
return result; return result;
} }
std::vector<External_Resource_Status> std::vector<External_Resource_Status>
External_Resources_Manager::status(SQLite::Database &db) const { External_Resources_Manager::status(SQLite::Database& db) const {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
std::vector<External_Resource_Status> result; std::vector<External_Resource_Status> result;
for (const auto &resource: resources_) { for (const auto& resource : resources_) {
result.push_back( result.push_back(
{resource->name, resource->row_count(db), false, false, ""}); {resource->name, resource->row_count(db), false, false, ""});
} }
return result; return result;
} }
SQLite::Database& External_Resources_Manager::require_db() const {
SQLite::Database &External_Resources_Manager::require_db() const {
if (!db_) { if (!db_) {
throw std::runtime_error("DB not loaded. Call load_sqlite_db() first."); throw std::runtime_error("DB not loaded. Call load_sqlite_db() first.");
} }
return *db_; return *db_;
} }
External_Resources& External_Resources_Manager::get_resource(
External_Resources &External_Resources_Manager::get_resource(
std::string_view resource_name) const { std::string_view resource_name) const {
for (const auto &resource: resources_) { for (const auto& resource : resources_) {
if (resource->name == resource_name) if (resource->name == resource_name)
return *resource; return *resource;
} }
throw std::invalid_argument("unknown external resource: " + std::string(resource_name)); throw std::invalid_argument("unknown external resource: " + std::string(resource_name));
} }
std::vector<External_Resource_Status> std::vector<External_Resource_Status>
External_Resources_Manager::update_all(SQLite::Database &db, External_Resources_Manager::update_all(SQLite::Database& db,
const bool force_download, const bool force_download,
const bool only_when_empty) { const bool only_when_empty) {
std::lock_guard lock(mtx_); std::lock_guard lock(mtx_);
std::vector<External_Resource_Status> result; std::vector<External_Resource_Status> result;
for (const auto &resource: resources_) { for (const auto& resource : resources_) {
External_Resource_Status status; External_Resource_Status status;
try { try {
status = status =
@@ -849,7 +774,8 @@ External_Resources_Manager::update_all(SQLite::Database &db,
std::cout << "External database [" << status.name << "] " std::cout << "External database [" << status.name << "] "
<< status.message << ", rows=" << status.row_count << std::endl; << status.message << ", rows=" << status.row_count << std::endl;
result.push_back(std::move(status)); result.push_back(std::move(status));
} catch (const std::exception &error) { }
catch (const std::exception& error) {
std::cerr << "External database [" << resource->name std::cerr << "External database [" << resource->name
<< "] update failed: [" << error.what() << "]" << " status.message:" << status.message << std::endl; << "] update failed: [" << error.what() << "]" << " status.message:" << status.message << std::endl;
result.push_back({ result.push_back({
+128 -43
View File
@@ -5,10 +5,8 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <string_view> #include <string_view>
BaseLogger* server_logger = nullptr;
BaseLogger *server_logger = nullptr;
Debug_Logger_Info_Manager debug_logger_info_manager; Debug_Logger_Info_Manager debug_logger_info_manager;
void Global::handle_old_logs() { void Global::handle_old_logs() {
auto mode = log_config.open_mode; auto mode = log_config.open_mode;
std::string dirPath = get_exe_dir() + "/" + "logs"; std::string dirPath = get_exe_dir() + "/" + "logs";
@@ -37,7 +35,8 @@ void Global::handle_old_logs() {
} }
if (fs::create_directories(dirPath)) { if (fs::create_directories(dirPath)) {
std::cout << "Directory created: " << dirPath << std::endl; std::cout << "Directory created: " << dirPath << std::endl;
} else { }
else {
std::cout << "创建目录失败: " << dirPath << std::endl; std::cout << "创建目录失败: " << dirPath << std::endl;
Psc::fail_fast(); Psc::fail_fast();
} }
@@ -51,13 +50,12 @@ void Global::handle_old_logs() {
std::cerr << "未知的打开模式!" << std::endl; std::cerr << "未知的打开模式!" << std::endl;
break; break;
} }
} catch (const std::exception &ex) { }
catch (const std::exception& ex) {
std::cerr << "Error: " + Psc::platform_2_utf8(ex.what()) + "\n"; std::cerr << "Error: " + Psc::platform_2_utf8(ex.what()) + "\n";
} }
} }
Global::Global() { Global::Global() {
auto j = load(); auto j = load();
log_config.from_base_json(j.get("log")); log_config.from_base_json(j.get("log"));
handle_old_logs(); handle_old_logs();
@@ -79,33 +77,31 @@ Global::Global() {
// piece_num); // piece_num);
server_logger = new BaseLogger("@/logs/server", MB * size_MB, piece_num); server_logger = new BaseLogger("@/logs/server", MB * size_MB, piece_num);
asio_socket::socket_logger->set_redirect( asio_socket::socket_logger->set_redirect(
[](const BaseLogger::Log_Info &log_info) { [](const BaseLogger::Log_Info& log_info) {
auto msg = "[" + std::string("func") + "~" + log_info.func_pattern + auto msg = "[" + std::string("func") + "~" + log_info.func_pattern +
"] " + log_info.log_type.to_string() + log_info.content; "] " + log_info.log_type.to_string() + log_info.content;
debug_logger_info_manager.push_info(msg); debug_logger_info_manager.push_info(msg);
}); });
serial::serial_logger->set_redirect([](const BaseLogger::Log_Info &log_info) { serial::serial_logger->set_redirect([](const BaseLogger::Log_Info& log_info) {
auto msg = "[" + std::string("func") + "~" + log_info.func_pattern + "] " + auto msg = "[" + std::string("func") + "~" + log_info.func_pattern + "] " +
log_info.log_type.to_string() + log_info.content; log_info.log_type.to_string() + log_info.content;
debug_logger_info_manager.push_info(msg); debug_logger_info_manager.push_info(msg);
}); });
fromJson(&j); fromJson(&j);
#ifdef Cache_Some_Mode_S #ifdef Cache_Some_Mode_S
auto old_parse_ok_json = SSR::parse_ok_json; auto old_parse_ok_json = SSR::parse_ok_json;
SSR::parse_ok_json = [old_parse_ok_json](Aircraft_Info *aircraft_info, SSR::parse_ok_json = [old_parse_ok_json](Aircraft_Info* aircraft_info,
SSR::P_S mode_s_msg, SSR::P_S mode_s_msg,
Psc::JSON json) { Psc::JSON json) {
old_parse_ok_json(aircraft_info, mode_s_msg, json); old_parse_ok_json(aircraft_info, mode_s_msg, json);
auto f = static_cast<Aircraft *>(aircraft_info); auto f = static_cast<Aircraft*>(aircraft_info);
f->add_msg_limit(mode_s_msg); f->add_msg_limit(mode_s_msg);
}; };
#endif #endif
SSR::cpr_cb = [](SSR::CPR_Error_Type t, std::string_view log, SSR::cpr_cb = [](SSR::CPR_Error_Type t, std::string_view log,
SSR::P_S msg) { SSR::P_S msg) {
auto src = std::dynamic_pointer_cast<Data_Source>(msg->source); auto src = std::dynamic_pointer_cast<Data_Source>(msg->source);
Mode_S_Statistic_Data *ss = &src->mode_s_statistic; Mode_S_Statistic_Data* ss = &src->mode_s_statistic;
if (t != SSR::CPR_Error_Type::Normal) { if (t != SSR::CPR_Error_Type::Normal) {
ss->add_cpr_error(t); ss->add_cpr_error(t);
} }
@@ -113,30 +109,31 @@ Global::Global() {
}; };
// 处理错误 // 处理错误
SSR::parse_call_back = SSR::parse_call_back =
[this](SSR::Parse_Call_Back_Type type, SSR::Aircraft_Info *info, [this](SSR::Parse_Call_Back_Type type, SSR::Aircraft_Info* info,
std::string_view field_name, std::vector<std::string> bds_list, std::string_view field_name, std::vector<std::string> bds_list,
void *, SSR::P_S msg) { void*, SSR::P_S msg) {
auto src = std::dynamic_pointer_cast<Data_Source>(msg->source); auto src = std::dynamic_pointer_cast<Data_Source>(msg->source);
Mode_S_Statistic_Data *ss = &src->mode_s_statistic; Mode_S_Statistic_Data* ss = &src->mode_s_statistic;
if (type == SSR::Parse_Call_Back_Type::Unknown_DF) { if (type == SSR::Parse_Call_Back_Type::Unknown_DF) {
// std::cout << "Unknown DF type!" << (int)(msg->df) << std::endl; // std::cout << "Unknown DF type!" << (int)(msg->df) << std::endl;
return; return;
} }
DF_Statistic_Data *dfs = ss->get_create_df_statistic_data(msg->df); DF_Statistic_Data* dfs = ss->get_create_df_statistic_data(msg->df);
dfs->add(); dfs->add();
if (type == SSR::Parse_Call_Back_Type::Normal_Block) { if (type == SSR::Parse_Call_Back_Type::Normal_Block) {
dfs->add_sub_part(field_name); dfs->add_sub_part(field_name);
info->update(msg); info->update(msg);
} else if (type == SSR::Parse_Call_Back_Type::CRC_Error) { }
else if (type == SSR::Parse_Call_Back_Type::CRC_Error) {
dfs->add_crc_error(); dfs->add_crc_error();
// std::cout << field_name << " :crc_error msg:" << msg->msg_hex << // std::cout << field_name << " :crc_error msg:" << msg->msg_hex <<
// " df:" << (int)msg->df << std::endl; // " df:" << (int)msg->df << std::endl;
} else if (type == SSR::Parse_Call_Back_Type::Length_Error) { }
else if (type == SSR::Parse_Call_Back_Type::Length_Error) {
ss->add_length_error(field_name); ss->add_length_error(field_name);
// std::cout << field_name << " :length_error msg:" << msg->msg_hex // std::cout << field_name << " :length_error msg:" << msg->msg_hex
// << " df:" << (int)msg->df << std::endl; // << " df:" << (int)msg->df << std::endl;
} }
// else if (type == Mode_S::Parse_Call_Back_Type::UNKNOWN_ERROR) {} else // else if (type == Mode_S::Parse_Call_Back_Type::UNKNOWN_ERROR) {} else
// {} // {}
}; };
@@ -150,9 +147,10 @@ Global::Global() {
// mode_s_log_info = mode_s_log; // mode_s_log_info = mode_s_log;
init_web_server(); init_web_server();
} }
Global::~Global() { std::cout << "Global::~Global()" << std::endl; } Global::~Global() {
std::cout << "Global::~Global()" << std::endl;
void replace(std::string &originalStr, std::string_view findStr, }
void replace(std::string& originalStr, std::string_view findStr,
std::string_view replaceStr) { std::string_view replaceStr) {
size_t pos = originalStr.find(findStr); size_t pos = originalStr.find(findStr);
while (pos != std::string::npos) { while (pos != std::string::npos) {
@@ -171,9 +169,9 @@ bool isHexadecimal(std::string_view str) {
}); });
} }
void handle_buffer_muti_start( void handle_buffer_muti_start(
std::string &buffer, std::string_view data, std::string& buffer, std::string_view data,
const std::set<std::string> &prefix_list, const std::set<std::string>& prefix_list,
const std::function<void(std::string &)> &callback) { const std::function<void(std::string&)>& callback) {
if (!data.empty()) { if (!data.empty()) {
buffer += data; buffer += data;
// std::cout << "[data]:" + data + "\n"; // std::cout << "[data]:" + data + "\n";
@@ -209,9 +207,9 @@ void handle_buffer_muti_start(
} }
} }
void handle_buffer_head_tail( void handle_buffer_head_tail(
std::string &buffer, std::string_view data, std::string_view prefix, std::string& buffer, std::string_view data, std::string_view prefix,
std::string_view suffix, std::string_view suffix,
const std::function<void(std::string &)> &callback) { const std::function<void(std::string&)>& callback) {
// 只在数据可用时进行读取 // 只在数据可用时进行读取
if (!data.empty()) { if (!data.empty()) {
buffer += data; buffer += data;
@@ -232,8 +230,7 @@ void handle_buffer_head_tail(
} }
} }
} }
void read_ais_serial_data(std::atomic<bool>& running) {
void read_ais_serial_data(std::atomic<bool> &running) {
// static int t = config.ais.read_serial_milliseconds; // static int t = config.ais.read_serial_milliseconds;
// static bool ais_log = config.console_config.ais_serial; // static bool ais_log = config.console_config.ais_serial;
// static bool use_ais_serial = !config.ais_mock.enable || // static bool use_ais_serial = !config.ais_mock.enable ||
@@ -266,14 +263,13 @@ void read_ais_serial_data(std::atomic<bool> &running) {
// } // }
// delete ais_serial; // delete ais_serial;
} }
bool is_10004(SSR::Mode_S_Msg &msg) { bool is_10004(SSR::Mode_S_Msg& msg) {
bool DF_11_17_18 = bool DF_11_17_18 =
msg.df == SSR::Downlink_Format::All_Call_Reply_11 || msg.df == SSR::Downlink_Format::All_Call_Reply_11 ||
msg.df == SSR::Downlink_Format::Extended_Squitter_17 || msg.df == SSR::Downlink_Format::Extended_Squitter_17 ||
msg.df == SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18; msg.df == SSR::Downlink_Format::Extended_Squitter_Non_Transponder_18;
return DF_11_17_18; return DF_11_17_18;
} }
std::string to_file_name(std::string_view str) { std::string to_file_name(std::string_view str) {
auto ret = std::string(str); auto ret = std::string(str);
// 定义允许的合法字符 // 定义允许的合法字符
@@ -283,7 +279,9 @@ std::string to_file_name(std::string_view str) {
}; };
// 替换非法字符为下划线 '_' // 替换非法字符为下划线 '_'
std::transform(ret.begin(), ret.end(), ret.begin(), std::transform(ret.begin(), ret.end(), ret.begin(),
[&](char c) { return is_valid_char(c) ? c : '_'; }); [&](char c) {
return is_valid_char(c) ? c : '_';
});
// 检查结果字符串是否全是替换字符,防止生成全是下划线的文件名 // 检查结果字符串是否全是替换字符,防止生成全是下划线的文件名
if (ret.find_first_not_of('_') == std::string::npos) { if (ret.find_first_not_of('_') == std::string::npos) {
return "default_file_name"; // 返回一个默认文件名 return "default_file_name"; // 返回一个默认文件名
@@ -312,7 +310,7 @@ JSON Debug_Logger_Info_Manager::to_json() {
return ret; return ret;
} }
bool Web_Server::listen(std::string_view host, int port) { bool Web_Server::listen(std::string_view host, int port) {
drogon::HttpAppFramework *app = &drogon::app(); drogon::HttpAppFramework* app = &drogon::app();
auto g = Global::instance(); auto g = Global::instance();
Json::Value drogon_config; Json::Value drogon_config;
{ {
@@ -339,7 +337,94 @@ bool Web_Server::listen(std::string_view host, int port) {
app->run(); app->run();
return true; return true;
} }
Web_Server& Web_Server::Post(std::string_view pattern, Handler handler) {
drogon::app().registerHandler(
std::string(pattern),
[handler](const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
handler(request, resp);
callback(resp);
},
{drogon::Post}
);
return *this;
}
Web_Server& Web_Server::Post_Coro(std::string_view pattern, CoroHandler handler) {
drogon::app().registerHandler(std::string(pattern), [handler = std::move(handler)](
const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
drogon::async_run(
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
try {
co_await handler(request, resp);
}
catch (const std::exception& error) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
std::terminate();
}
catch (...) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
std::terminate();
}
callback(resp);
co_return;
});
},
{drogon::Post}
);
return *this;
}
Web_Server& Web_Server::Get(std::string_view pattern, Handler handler) {
drogon::app().registerHandlerViaRegex(
std::string(pattern),
[handler](const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
handler(request, resp);
callback(resp);
},
{drogon::Get}
);
return *this;
}
Web_Server& Web_Server::Get_Coro(std::string_view pattern, CoroHandler handler) {
drogon::app().registerHandlerViaRegex(
std::string(pattern),
[handler = std::move(handler)](
const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
drogon::async_run(
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
try {
co_await handler(request, resp);
}
catch (const std::exception& error) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
std::terminate();
}
catch (...) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
std::terminate();
}
callback(resp);
co_return;
});
},
{drogon::Get}
);
return *this;
}
std::string std::string
Debug_Logger_Info_Manager::get_info(Serial_Number_Type serial_number) { Debug_Logger_Info_Manager::get_info(Serial_Number_Type serial_number) {
std::lock_guard g(mtx); std::lock_guard g(mtx);
@@ -354,26 +439,26 @@ Debug_Logger_Info_Manager::get_info(Serial_Number_Type serial_number) {
// << it->sequence << " content.size" << it->content.size() << std::endl; // << it->sequence << " content.size" << it->content.size() << std::endl;
if (it->sequence >= serial_number) { if (it->sequence >= serial_number) {
result = it->content + result; // 叠加 content result = it->content + result; // 叠加 content
} else { }
else {
break; break;
} }
} }
return result; return result;
} }
std::string inet_address_to_string(const trantor::InetAddress& addr) {
std::string inet_address_to_string(const trantor::InetAddress &addr) {
char buf[INET6_ADDRSTRLEN] = {0}; char buf[INET6_ADDRSTRLEN] = {0};
if (!addr.isIpV6()) { if (!addr.isIpV6()) {
// IPv4 // IPv4
auto sa = reinterpret_cast<const struct sockaddr_in *>(addr.getSockAddr()); auto sa = reinterpret_cast<const struct sockaddr_in*>(addr.getSockAddr());
inet_ntop(AF_INET, &(sa->sin_addr), buf, sizeof(buf)); inet_ntop(AF_INET, &(sa->sin_addr), buf, sizeof(buf));
uint16_t port = ntohs(sa->sin_port); uint16_t port = ntohs(sa->sin_port);
return std::string(buf) + ":" + std::to_string(port); return std::string(buf) + ":" + std::to_string(port);
} else { }
else {
// IPv6 // IPv6
auto sa6 = auto sa6 =
reinterpret_cast<const struct sockaddr_in6 *>(addr.getSockAddr()); reinterpret_cast<const struct sockaddr_in6*>(addr.getSockAddr());
inet_ntop(AF_INET6, &(sa6->sin6_addr), buf, sizeof(buf)); inet_ntop(AF_INET6, &(sa6->sin6_addr), buf, sizeof(buf));
uint16_t port = ntohs(sa6->sin6_port); uint16_t port = ntohs(sa6->sin6_port);
return "[" + std::string(buf) + "]:" + std::to_string(port); return "[" + std::string(buf) + "]:" + std::to_string(port);
+26 -151
View File
@@ -1,8 +1,5 @@
#pragma once #pragma once
#include <string_view> #include <string_view>
#include "Core/Base/ThreadManager.h" #include "Core/Base/ThreadManager.h"
#include "../Data_Source/export.h" #include "../Data_Source/export.h"
#include "../State_Report/State_Report.h" #include "../State_Report/State_Report.h"
@@ -10,9 +7,7 @@
#include "Ucoro_Drogon_Glue.h" #include "Ucoro_Drogon_Glue.h"
#include "Config.h" #include "Config.h"
#include <drogon/drogon.h> #include <drogon/drogon.h>
#include "Config.h" #include "Config.h"
#include "../../Radarcape_Core/cpp-httplib/httplib.h" #include "../../Radarcape_Core/cpp-httplib/httplib.h"
#include "../Data_Source/export.h" #include "../Data_Source/export.h"
#include "Core/Net_Adapter/Net_Adapter.h" #include "Core/Net_Adapter/Net_Adapter.h"
@@ -20,13 +15,11 @@
#include <filesystem> #include <filesystem>
#include <list> #include <list>
#include <utility> #include <utility>
// 集中 管理日志 // 集中 管理日志
using namespace Psc; using namespace Psc;
extern BaseLogger* server_logger; extern BaseLogger* server_logger;
std::string to_file_name(std::string_view str); std::string to_file_name(std::string_view str);
std::string inet_address_to_string(const trantor::InetAddress &addr); std::string inet_address_to_string(const trantor::InetAddress& addr);
using Serial_Number_Type = unsigned int; using Serial_Number_Type = unsigned int;
struct Debug_Logger_Info_Manager { struct Debug_Logger_Info_Manager {
void push_info(std::string_view content); void push_info(std::string_view content);
@@ -47,24 +40,17 @@ private:
std::mutex mtx; std::mutex mtx;
}; };
extern Debug_Logger_Info_Manager debug_logger_info_manager; extern Debug_Logger_Info_Manager debug_logger_info_manager;
#define RET_OK \ #define RET_OK \
res.status = StatusCode::OK_200; \ res.status = StatusCode::OK_200; \
res.set_content("{\"status\": 200}", "application/json"); res.set_content("{\"status\": 200}", "application/json");
inline JSON warp(const JSON& data) { inline JSON warp(const JSON& data) {
// Json ret = Json::object(); // Json ret = Json::object();
// ret.append({"status", 200}); // ret.append({"status", 200});
// ret.append({"data", data}); // ret.append({"data", data});
// return ret; // return ret;
return data; return data;
} }
#define HTTP_Param const drogon::HttpRequestPtr& req, const drogon::HttpResponsePtr& res #define HTTP_Param const drogon::HttpRequestPtr& req, const drogon::HttpResponsePtr& res
class Web_Server { class Web_Server {
public: public:
std::string update = "update_"; std::string update = "update_";
@@ -76,125 +62,22 @@ public:
using Handler = std::function<void(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>; using Handler = std::function<void(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
using CoroHandler = std::function<drogon::Task<>(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>; using CoroHandler = std::function<drogon::Task<>(const drogon::HttpRequestPtr&, const drogon::HttpResponsePtr&)>;
bool listen(std::string_view host, int port); bool listen(std::string_view host, int port);
~Web_Server() = default; ~Web_Server() = default;
static void stop() { static void stop() {
std::cout << "开始停止web服务" << std::endl; std::cout << "开始停止web服务" << std::endl;
drogon::app().quit(); drogon::app().quit();
} }
Web_Server& Post(std::string_view pattern, Handler handler);
Web_Server& Post(std::string_view pattern, Handler handler) { Web_Server& Post_Coro(std::string_view pattern, CoroHandler handler);
drogon::app().registerHandler( Web_Server& Get(std::string_view pattern, Handler handler);
std::string(pattern), Web_Server& Get_Coro(std::string_view pattern, CoroHandler handler);
[handler](const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
handler(request, resp);
callback(resp);
},
{drogon::Post}
);
return *this;
}
Web_Server& PostCoro(std::string_view pattern, CoroHandler handler) {
drogon::app().registerHandler(
std::string(pattern),
[handler = std::move(handler)](
const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
drogon::async_run(
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
try {
co_await handler(request, resp);
} catch (const std::exception& error) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
} catch (...) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
}
callback(resp);
co_return;
});
},
{drogon::Post}
);
return *this;
}
Web_Server& Get(std::string_view pattern, Handler handler) {
drogon::app().registerHandlerViaRegex(
std::string(pattern),
[handler](const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
handler(request, resp);
callback(resp);
},
{drogon::Get}
);
return *this;
}
Web_Server& GetCoro(std::string_view pattern, CoroHandler handler) {
drogon::app().registerHandlerViaRegex(
std::string(pattern),
[handler = std::move(handler)](
const drogon::HttpRequestPtr& request,
std::function<void(const drogon::HttpResponsePtr&)>&& callback) {
auto resp = drogon::HttpResponse::newHttpResponse();
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
drogon::async_run(
[handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> {
try {
co_await handler(request, resp);
} catch (const std::exception& error) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string());
} catch (...) {
resp->setStatusCode(drogon::k500InternalServerError);
resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string());
}
callback(resp);
co_return;
});
},
{drogon::Get}
);
return *this;
}
}; };
// 这个对象不释放 // 这个对象不释放
class Mlat_MSG { class Mlat_MSG {
public: public:
explicit Mlat_MSG(const std::shared_ptr<SSR::Mode_Msg>& first) { list.push_back(first);} explicit Mlat_MSG(const std::shared_ptr<SSR::Mode_Msg>& first) {
list.push_back(first);
}
[[nodiscard]] std::optional<std::string> icao() const { [[nodiscard]] std::optional<std::string> icao() const {
auto a = list[0]; auto a = list[0];
auto t = a->type; auto t = a->type;
@@ -203,21 +86,26 @@ public:
} }
return std::nullopt; return std::nullopt;
} }
[[nodiscard]] std::string msg_hex() const { return list[0]->msg_hex;} [[nodiscard]] std::string msg_hex() const {
[[nodiscard]] SSR::Mode_Msg::T type() const { return static_cast<SSR::Mode_Msg::T>(list[0]->type);} return list[0]->msg_hex;
[[nodiscard]] SSR::MLAT_timestamp& timestamp() const { return list[0]->mlat_timestamp;} }
[[nodiscard]] std::shared_ptr<SSR::Data_Source_Interface> data_source() const { return list[0]->source;} [[nodiscard]] SSR::Mode_Msg::T type() const {
return static_cast<SSR::Mode_Msg::T>(list[0]->type);
}
[[nodiscard]] SSR::MLAT_timestamp& timestamp() const {
return list[0]->mlat_timestamp;
}
[[nodiscard]] std::shared_ptr<SSR::Data_Source_Interface> data_source() const {
return list[0]->source;
}
void add(const std::shared_ptr<SSR::Mode_Msg>& t) { void add(const std::shared_ptr<SSR::Mode_Msg>& t) {
list.push_back(t); list.push_back(t);
} }
[[nodiscard]] size_t size() const { return list.size(); } [[nodiscard]] size_t size() const {
return list.size();
}
std::vector<std::shared_ptr<SSR::Mode_Msg>> list; std::vector<std::shared_ptr<SSR::Mode_Msg>> list;
}; };
class Mlat_Handler { class Mlat_Handler {
public: public:
std::list<Mlat_MSG> get_all() { std::list<Mlat_MSG> get_all() {
@@ -227,18 +115,14 @@ public:
std::swap(ok_list, ret); std::swap(ok_list, ret);
return ret; return ret;
} }
void push(const std::shared_ptr<SSR::Mode_Msg>& msg) { void push(const std::shared_ptr<SSR::Mode_Msg>& msg) {
std::lock_guard<std::mutex> g(mtx); std::lock_guard<std::mutex> g(mtx);
if (list.empty()) { if (list.empty()) {
list.emplace_back(msg); list.emplace_back(msg);
return; return;
} }
auto time = msg->mlat_timestamp; auto time = msg->mlat_timestamp;
auto p = list.rbegin(); auto p = list.rbegin();
while (p != list.rend()) { while (p != list.rend()) {
auto cur_time = p->timestamp(); auto cur_time = p->timestamp();
// 往前最多找3秒 // 往前最多找3秒
@@ -261,12 +145,7 @@ protected:
std::mutex ok_mtx; std::mutex ok_mtx;
std::mutex mtx; std::mutex mtx;
}; };
class Global : public Config, public Singleton<Global> {
class Global : public Config, public Singleton<Global>{
public: public:
// asio::io_context ctx; // asio::io_context ctx;
std::atomic<bool> init_ok{false}; std::atomic<bool> init_ok{false};
@@ -277,8 +156,7 @@ public:
return mode_acs.data_source_config.map.get(std::string(data_source_key)).value_or(nullptr); return mode_acs.data_source_config.map.get(std::string(data_source_key)).value_or(nullptr);
} }
std::shared_ptr<Data_Source> total_source() { std::shared_ptr<Data_Source> total_source() {
for (auto i : mode_acs.data_source_config.map.list()) for (auto i : mode_acs.data_source_config.map.list()) {
{
if (i->enable) return i; if (i->enable) return i;
} }
return mode_acs.data_source_config.map.list().at(0); return mode_acs.data_source_config.map.list().at(0);
@@ -291,9 +169,6 @@ public:
std::time_t start_server_time; std::time_t start_server_time;
DELETE_COPY(Global) DELETE_COPY(Global)
}; };
void handle_buffer_muti_start(std::string& buffer, std::string_view data, const std::set<std::string>& prefix_list, void handle_buffer_muti_start(std::string& buffer, std::string_view data, const std::set<std::string>& prefix_list,
const std::function<void(std::string&)>& callback); const std::function<void(std::string&)>& callback);
void handle_buffer_head_tail(std::string& buffer, std::string_view data, std::string_view prefix, void handle_buffer_head_tail(std::string& buffer, std::string_view data, std::string_view prefix,
+1 -5
View File
@@ -10,11 +10,7 @@ fetch_repo() {
local branch="$2" local branch="$2"
local dir="$3" local dir="$3"
if [ -d "$dir" ]; then if [ -d "$dir" ]; then
git -C "$dir" rev-parse --is-inside-work-tree >/dev/null echo "文件夹【$dir】已存在 跳过初始化 "
git -C "$dir" remote set-url origin "$repo"
git -C "$dir" fetch origin "$branch"
git -C "$dir" checkout "$branch"
git -C "$dir" pull --ff-only origin "$branch"
else else
git clone --branch "$branch" --single-branch "$repo" "$dir" git clone --branch "$branch" --single-branch "$repo" "$dir"
fi fi
-44
View File
@@ -1,44 +0,0 @@
$ErrorActionPreference = "Stop"
$scriptDir = $PSScriptRoot
if ( [string]::IsNullOrWhiteSpace($scriptDir))
{
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
}
$root = (Resolve-Path -LiteralPath (Join-Path $scriptDir "..")).Path
Set-Location -LiteralPath $root
$origin = git remote get-url origin
$origin = $origin.TrimEnd("/")
$remoteRoot = $origin -replace "/[^/]+(\.git)?$", ""
function Fetch-Repo
{
param(
[string]$Repo,
[string]$Branch,
[string]$Dir
)
if (Test-Path -LiteralPath $Dir -PathType Container)
{
git -C $Dir rev-parse --is-inside-work-tree *> $null
git -C $Dir remote set-url origin $Repo
git -C $Dir fetch origin $Branch
git -C $Dir checkout $Branch
git -C $Dir pull --ff-only origin $Branch
}
else
{
git clone --branch $Branch --single-branch $Repo $Dir
}
}
function Fetch-RepoEx
{
param(
[string]$Name
)
$repo = "$remoteRoot/$Name"
$branch = "master"
Fetch-Repo -Repo $repo -Branch $branch -Dir "third_party/$Name"
}
Fetch-RepoEx "build_infra"
Fetch-RepoEx "CPP_Core"
Fetch-RepoEx "SSR"
Fetch-RepoEx "eacp_webapp"
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
node_dir="/c/Users/wyc/AppData/Roaming/JetBrains/WebStorm2026.1/node/versions/24.18.0"
export PATH="$node_dir:$PATH"
cd "$root/third_party/eacp_webapp"
node --version
npm --version
npm run dev -- --host 0.0.0.0