优化 OPC UA event_loop 监控和重连机制
This commit is contained in:
parent
76b6e17927
commit
d4d5749ccc
|
|
@ -99,6 +99,7 @@ pub struct ConnectionStatus {
|
||||||
poll_handle: Option<JoinHandle<()>>, // 统一的轮询任务句柄
|
poll_handle: Option<JoinHandle<()>>, // 统一的轮询任务句柄
|
||||||
heartbeat_handle: Option<JoinHandle<()>>, // 心跳任务句柄
|
heartbeat_handle: Option<JoinHandle<()>>, // 心跳任务句柄
|
||||||
event_loop_handle: Option<JoinHandle<opcua::types::StatusCode>>, // event_loop 任务句柄
|
event_loop_handle: Option<JoinHandle<opcua::types::StatusCode>>, // event_loop 任务句柄
|
||||||
|
event_loop_monitor_handle: Option<JoinHandle<()>>, // event_loop 监控任务句柄
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -579,6 +580,33 @@ impl ConnectionManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
let event_loop_handle = event_loop.spawn();
|
let event_loop_handle = event_loop.spawn();
|
||||||
|
|
||||||
|
// 添加监控任务来捕获 event_loop 结束事件
|
||||||
|
let manager = self.clone();
|
||||||
|
let source_id_copy = source_id;
|
||||||
|
let event_loop_monitor_handle = tokio::spawn(async move {
|
||||||
|
match event_loop_handle.await {
|
||||||
|
Ok(status) => {
|
||||||
|
tracing::warn!(
|
||||||
|
"OPCUA event loop ended for source {}: {:?}",
|
||||||
|
source_id_copy,
|
||||||
|
status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!(
|
||||||
|
"OPCUA event loop panic for source {}: {}",
|
||||||
|
source_id_copy,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一触发重连
|
||||||
|
if let Some(tx) = manager.reconnect_tx.as_ref() {
|
||||||
|
let _ = tx.send(source_id_copy);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if !session.wait_for_connection().await {
|
if !session.wait_for_connection().await {
|
||||||
let error = "Session connection failed".to_string();
|
let error = "Session connection failed".to_string();
|
||||||
|
|
@ -601,7 +629,8 @@ impl ConnectionManager {
|
||||||
poll_points: Arc::new(Vec::new()),
|
poll_points: Arc::new(Vec::new()),
|
||||||
poll_handle: None,
|
poll_handle: None,
|
||||||
heartbeat_handle: None,
|
heartbeat_handle: None,
|
||||||
event_loop_handle: Some(event_loop_handle),
|
event_loop_handle: None, // event_loop_handle 已被移动到监控任务中
|
||||||
|
event_loop_monitor_handle: Some(event_loop_monitor_handle),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
drop(status); // 显式释放锁,在调用 start_unified_poll_task 之前
|
drop(status); // 显式释放锁,在调用 start_unified_poll_task 之前
|
||||||
|
|
@ -633,6 +662,7 @@ impl ConnectionManager {
|
||||||
poll_handle: None,
|
poll_handle: None,
|
||||||
heartbeat_handle: None,
|
heartbeat_handle: None,
|
||||||
event_loop_handle: None,
|
event_loop_handle: None,
|
||||||
|
event_loop_monitor_handle: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -673,6 +703,10 @@ impl ConnectionManager {
|
||||||
if let Some(handle) = conn_status.event_loop_handle.take() {
|
if let Some(handle) = conn_status.event_loop_handle.take() {
|
||||||
handle.abort();
|
handle.abort();
|
||||||
}
|
}
|
||||||
|
// 停止 event_loop 监控任务
|
||||||
|
if let Some(handle) = conn_status.event_loop_monitor_handle.take() {
|
||||||
|
handle.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -709,6 +743,10 @@ impl ConnectionManager {
|
||||||
if let Some(handle) = conn_status.event_loop_handle.take() {
|
if let Some(handle) = conn_status.event_loop_handle.take() {
|
||||||
handle.abort();
|
handle.abort();
|
||||||
}
|
}
|
||||||
|
// 停止 event_loop 监控任务
|
||||||
|
if let Some(handle) = conn_status.event_loop_monitor_handle.take() {
|
||||||
|
handle.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue