协程对外抛异常
This commit is contained in:
@@ -1,105 +1,140 @@
|
||||
#include "With_Loop_Coro.h"
|
||||
#include "io_coro.h"
|
||||
#include <string_view>
|
||||
|
||||
With_Loop_Coro::~With_Loop_Coro() = default;
|
||||
|
||||
void With_Loop_Coro::async_stop() {
|
||||
std::string name = type + ":" + key;
|
||||
set_state(State::Force_Quit, std::format("任务正常收到请求,等待退出 {}!\n", name).c_str());
|
||||
loop_running = false;
|
||||
std::string name = type + ":" + key;
|
||||
set_state(State::Force_Quit, std::format("任务正常收到请求,等待退出 {}!\n", name).c_str());
|
||||
loop_running = false;
|
||||
}
|
||||
|
||||
void With_Loop_Coro::sync_wait() {
|
||||
std::string name = type + ":" + key;
|
||||
if (!loop_task) {
|
||||
std::cout << std::format("{}退出成功! loop_task 未启动 \n", name);
|
||||
return;
|
||||
}
|
||||
while (loop_task->wait_for(std::chrono::milliseconds(0)) != std::future_status::ready) {
|
||||
std::cout << std::format("{}等待退出 当前状态为{} \n", name, Psc::to_string(this->state));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
}
|
||||
std::cout << std::format("{}退出成功! \n", name);
|
||||
std::string name = type + ":" + key;
|
||||
if (!loop_task) {
|
||||
std::cout << std::format("{}退出成功! loop_task 未启动 \n", name);
|
||||
return;
|
||||
}
|
||||
while (loop_task->wait_for(std::chrono::milliseconds(0)) != std::future_status::ready) {
|
||||
std::cout << std::format("{}等待退出 当前状态为{} \n", name, Psc::to_string(this->state));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
}
|
||||
std::cout << std::format("{}退出成功! \n", name);
|
||||
}
|
||||
|
||||
bool With_Loop_Coro::running() const {
|
||||
return loop_running;
|
||||
return loop_running.load();
|
||||
}
|
||||
|
||||
void With_Loop_Coro::set_state(State state, std::string_view action) {
|
||||
if (!action.empty()) {
|
||||
std::string name = type + "_" + key;
|
||||
std::cout << std::format("协程状态机 {} {} {} ==> {} \n", name, action, Psc::to_string(this->state),
|
||||
Psc::to_string(state));
|
||||
}
|
||||
this->state = state;
|
||||
if (!action.empty()) {
|
||||
std::string name = type + "_" + key;
|
||||
std::cout << std::format("协程状态机 {} {} {} ==> {} \n", name, action, Psc::to_string(this->state),
|
||||
Psc::to_string(state));
|
||||
}
|
||||
this->state = state;
|
||||
}
|
||||
|
||||
With_Loop_Coro::With_Loop_Coro() : stop(0.1) {
|
||||
}
|
||||
|
||||
With_Loop_Coro::With_Loop_Coro() : stop(0.1) {}
|
||||
asio::awaitable<void> With_Loop_Coro::run_loop_coro() {
|
||||
loop_running.store(true, std::memory_order_release);
|
||||
try {
|
||||
co_await loop_coro();
|
||||
loop_running.store(false, std::memory_order_release);
|
||||
co_return;
|
||||
} catch (...) {
|
||||
loop_running.store(false, std::memory_order_release);
|
||||
throw;
|
||||
}
|
||||
loop_running.store(true, std::memory_order_release);
|
||||
try {
|
||||
co_await loop_coro();
|
||||
loop_running.store(false, std::memory_order_release);
|
||||
co_return;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
//loop_running.store(false, std::memory_order_release);
|
||||
auto str = std::format("{} loop_coro 异常退出: {}\n", key, e.what());
|
||||
std::cerr << str;
|
||||
set_state(State::Loop_Exception, str);
|
||||
throw;
|
||||
}
|
||||
catch (...) {
|
||||
//loop_running.store(false, std::memory_order_release);
|
||||
std::cerr << "loop_coro 未知异常退出\n";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
asio::awaitable<void> With_Loop_Coro::tick() {
|
||||
std::string name = type + ":" + key;
|
||||
if (state == State::Force_Quit) {
|
||||
static Frequency_Limit_Multi flm;
|
||||
if (flm.test(name)) {
|
||||
std::cout << std::format("{} 正在强制退出!\n", name);
|
||||
}
|
||||
}
|
||||
if (state == State::Start) {
|
||||
if (enable) {
|
||||
set_state(State::Before_Request_Start_Loop);
|
||||
}
|
||||
} else if (state == State::Before_Request_Start_Loop) {
|
||||
co_await this->_open();
|
||||
loop_running = enable;
|
||||
loop_task = Coro::instance()->spawn(run_loop_coro());
|
||||
set_state(State::Waiting_Loop_Start, "开始启动任务");
|
||||
} else if (state == State::Waiting_Loop_Start) {
|
||||
if (running()) {
|
||||
set_state(State::Loop_Running, "启动任务成功!");
|
||||
}
|
||||
} else if (state == State::Loop_Running) {
|
||||
if (enable && !running()) {
|
||||
std::cout << std::format("任务未知原因已经退出 {}!\n", name);
|
||||
try {
|
||||
loop_task->get();
|
||||
} catch (const std::exception &e) {
|
||||
std::cout << std::format("任务异常退出 {}! {}\n", name, e.what());
|
||||
loop_running = false;
|
||||
} catch (...) {
|
||||
std::cout << std::format("任务未知异常退出 {}!\n", name);
|
||||
loop_running = false;
|
||||
}
|
||||
loop_task.reset();
|
||||
co_await _close();
|
||||
co_return;
|
||||
}
|
||||
if (!enable) {
|
||||
set_state(State::Before_Request_Stop_Loop, std::format("{} 检测到 enable变化 异步退出开始!", name));
|
||||
}
|
||||
} else if (state == State::Before_Request_Stop_Loop) {
|
||||
loop_running = false;
|
||||
set_state(State::Waiting_Stop_Loop, "退出变量已设置 等待退出");
|
||||
} else if (state == State::Waiting_Stop_Loop) {
|
||||
if (!running()) {
|
||||
loop_task.reset();
|
||||
co_await this->_close();
|
||||
set_state(State::Start, "任务正常退出");
|
||||
}
|
||||
}
|
||||
co_return;
|
||||
std::string name = type + ":" + key;
|
||||
if (state == State::Force_Quit) {
|
||||
static Frequency_Limit_Multi flm;
|
||||
if (flm.test(name)) {
|
||||
std::cout << std::format("{} 正在强制退出!\n", name);
|
||||
}
|
||||
}
|
||||
if (state == State::Start) {
|
||||
if (enable) {
|
||||
set_state(State::Before_Request_Start_Loop);
|
||||
}
|
||||
}
|
||||
else if (state == State::Before_Request_Start_Loop) {
|
||||
co_await this->_open();
|
||||
loop_running = enable;
|
||||
auto future = asio::co_spawn(Coro::instance()->io, run_loop_coro(), asio::use_future);
|
||||
loop_task = std::make_shared<std::future<void>>(std::move(future));
|
||||
//loop_task = Coro::instance()->spawn(run_loop_coro());
|
||||
// loop_task = asio::co_spawn(Coro::instance()->io, run_loop_coro(), [](std::exception_ptr exception) {
|
||||
// if (exception) {
|
||||
// std::cout << " 发生了异常!" << std::endl;
|
||||
// std::rethrow_exception(exception);
|
||||
// }
|
||||
// });
|
||||
set_state(State::Waiting_Loop_Start, "开始启动任务");
|
||||
}
|
||||
else if (state == State::Waiting_Loop_Start) {
|
||||
if (running()) {
|
||||
set_state(State::Loop_Running, "启动任务成功!");
|
||||
}
|
||||
}
|
||||
else if (state == State::Loop_Running) {
|
||||
if (!enable) {
|
||||
set_state(State::Before_Request_Stop_Loop, std::format("{} 检测到 enable变化 异步退出开始!", name));
|
||||
}
|
||||
}
|
||||
else if (state == State::Loop_Exception) {
|
||||
bool catch_exception = false;
|
||||
if (!catch_exception) {
|
||||
loop_task->get();
|
||||
}
|
||||
else {
|
||||
std::exception_ptr task_exception;
|
||||
try {
|
||||
// 走到这里直接崩溃
|
||||
loop_task->get();
|
||||
}
|
||||
catch (...) {
|
||||
task_exception = std::current_exception();
|
||||
}
|
||||
loop_task.reset();
|
||||
co_await _close();
|
||||
if (task_exception) {
|
||||
loop_running = false;
|
||||
try {
|
||||
std::rethrow_exception(task_exception);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cout << std::format("任务异常退出 {}! {}\n", name, e.what()) << std::flush;
|
||||
}
|
||||
catch (...) {
|
||||
std::cout << std::format("任务未知异常退出 {}!\n", name) << std::flush;
|
||||
}
|
||||
set_state(State::Start, "任务异常退出");
|
||||
co_return;
|
||||
}
|
||||
else {
|
||||
std::cout << "没有异常 状态机 紊乱" << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
else if (state == State::Before_Request_Stop_Loop) {
|
||||
loop_running = false;
|
||||
set_state(State::Waiting_Stop_Loop, "退出变量已设置 等待退出");
|
||||
}
|
||||
else if (state == State::Waiting_Stop_Loop) {
|
||||
if (!running()) {
|
||||
loop_task.reset();
|
||||
co_await this->_close();
|
||||
set_state(State::Start, "任务正常退出");
|
||||
}
|
||||
}
|
||||
co_return;
|
||||
}
|
||||
|
||||
@@ -16,35 +16,36 @@
|
||||
#include "Core/Statistics/Frequency_Limit.h"
|
||||
class With_Loop_Coro_Data {
|
||||
public:
|
||||
std::string type;
|
||||
std::string key;
|
||||
Psc::Copyable_Atomic<bool> enable{};
|
||||
PSC_USE_JSON
|
||||
std::string type;
|
||||
std::string key;
|
||||
Psc::Copyable_Atomic<bool> enable{};
|
||||
PSC_USE_JSON
|
||||
};
|
||||
class With_Loop_Coro : public With_Loop_Coro_Data {
|
||||
public:
|
||||
virtual ~With_Loop_Coro();
|
||||
std::shared_ptr<std::future<void>> loop_task;
|
||||
virtual asio::awaitable<void> loop_coro() = 0;
|
||||
void async_stop();
|
||||
void sync_wait();
|
||||
bool running() const;
|
||||
asio::awaitable<void> tick();
|
||||
virtual asio::awaitable<void> _open() = 0;
|
||||
virtual asio::awaitable<void> _close() = 0;
|
||||
enum class State {
|
||||
Force_Quit,
|
||||
Start,
|
||||
Before_Request_Start_Loop,
|
||||
Waiting_Loop_Start,
|
||||
Loop_Running,
|
||||
Before_Request_Stop_Loop,
|
||||
Waiting_Stop_Loop
|
||||
} state = State::Start;
|
||||
void set_state(State state, std::string_view action = "");
|
||||
With_Loop_Coro();
|
||||
virtual ~With_Loop_Coro();
|
||||
std::shared_ptr<std::future<void>> loop_task;
|
||||
virtual asio::awaitable<void> loop_coro() = 0;
|
||||
void async_stop();
|
||||
void sync_wait();
|
||||
bool running() const;
|
||||
asio::awaitable<void> tick();
|
||||
virtual asio::awaitable<void> _open() = 0;
|
||||
virtual asio::awaitable<void> _close() = 0;
|
||||
enum class State {
|
||||
Force_Quit,
|
||||
Start,
|
||||
Before_Request_Start_Loop,
|
||||
Waiting_Loop_Start,
|
||||
Loop_Running,
|
||||
Loop_Exception,
|
||||
Before_Request_Stop_Loop,
|
||||
Waiting_Stop_Loop
|
||||
} state = State::Start;
|
||||
void set_state(State state, std::string_view action = "");
|
||||
With_Loop_Coro();
|
||||
protected:
|
||||
Psc::Copyable_Atomic<bool> loop_running{};
|
||||
asio::awaitable<void> run_loop_coro();
|
||||
Frequency_Limit_Multi stop;
|
||||
Psc::Copyable_Atomic<bool> loop_running{};
|
||||
asio::awaitable<void> run_loop_coro();
|
||||
Frequency_Limit_Multi stop;
|
||||
};
|
||||
|
||||
@@ -82,6 +82,7 @@ void Coro::start() {
|
||||
auto promise = std::make_shared<std::promise<void> >();
|
||||
loop_task = std::make_unique<std::future<void> >(promise->get_future());
|
||||
asio::co_spawn(io, coro_thread(), [promise](std::exception_ptr ep) {
|
||||
std::cout << "发生了异常" << std::endl;
|
||||
if (ep) {
|
||||
promise->set_exception(ep);
|
||||
std::rethrow_exception(ep);
|
||||
|
||||
@@ -31,6 +31,15 @@ public:
|
||||
return std::make_shared<std::future<void> >(std::move(future));
|
||||
}
|
||||
|
||||
// template<typename Awaitable>
|
||||
// void spawn(Awaitable &&awaitable) {
|
||||
// asio::co_spawn(io, std::forward<Awaitable>(awaitable), [](std::exception_ptr exception) {
|
||||
// if (exception) {
|
||||
// std::rethrow_exception(exception);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
private:
|
||||
asio::awaitable<void> coro_thread();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user