优化: 飞书渠道文本链路与资源释放
This commit is contained in:
@@ -28,14 +28,20 @@ use crate::config::FeishuConfig;
|
||||
/// 飞书适配器:channel 归一化消息 + 卡片审批,单飞书应用单实例
|
||||
#[derive(Clone)]
|
||||
pub struct FeishuAdapter {
|
||||
client: LarkClient,
|
||||
/// 常驻 client(&'static,构造期一次性 Box::leak)。D1(u-claw 教训:热重建不关旧
|
||||
/// 连接→僵尸资源):leak 只在 new()/offline() 各发生一次;run() 重连重入只重建
|
||||
/// Channel 不再重复 leak,防频繁断线场景 LarkClient 内存阶梯上涨。出站 dispatch
|
||||
/// 与 Channel 构建共用同一份引用。
|
||||
client: &'static LarkClient,
|
||||
/// 流式会话注册表:chat_id → 已发出的流式消息 message_id(用于 edit_text 覆写)
|
||||
streams: Arc<tokio::sync::Mutex<HashMap<String, String>>>,
|
||||
}
|
||||
|
||||
impl FeishuAdapter {
|
||||
pub fn new(cfg: &FeishuConfig) -> anyhow::Result<Self> {
|
||||
let client = LarkClient::builder(&cfg.app_id, &cfg.app_secret).build()?;
|
||||
let client: &'static LarkClient = Box::leak(Box::new(
|
||||
LarkClient::builder(&cfg.app_id, &cfg.app_secret).build()?,
|
||||
));
|
||||
Ok(Self {
|
||||
client,
|
||||
streams: Arc::new(tokio::sync::Mutex::new(HashMap::new())),
|
||||
@@ -44,8 +50,11 @@ impl FeishuAdapter {
|
||||
|
||||
/// 构造失败时的离线哨兵:client 用占位凭证(不启动 run,dispatch 记日志即弃)
|
||||
pub fn offline() -> Self {
|
||||
let client = LarkClient::builder("offline", "offline").build()
|
||||
.expect("占位凭证构造 LarkClient 不发网络请求,必成功");
|
||||
let client: &'static LarkClient = Box::leak(Box::new(
|
||||
LarkClient::builder("offline", "offline")
|
||||
.build()
|
||||
.expect("占位凭证构造 LarkClient 不发网络请求,必成功"),
|
||||
));
|
||||
Self {
|
||||
client,
|
||||
streams: Arc::new(tokio::sync::Mutex::new(HashMap::new())),
|
||||
@@ -68,16 +77,16 @@ impl PlatformAdapter for FeishuAdapter {
|
||||
async fn run(&self, events: Sender<InboundEvent>) -> anyhow::Result<()> {
|
||||
// 长连接模式:空 verification_token/encrypt_key(免公网回调)
|
||||
let dispatcher = EventDispatcher::new("", "");
|
||||
let client = self.client.clone();
|
||||
let client = self.client;
|
||||
|
||||
// 入站事件通道复制两份,分别给消息/卡片回调闭包
|
||||
let events_for_msg = events.clone();
|
||||
let events_for_card = events;
|
||||
|
||||
let channel: Channel<'static> = {
|
||||
// Channel<'a> 借用 client;用 Box::leak 提升为 'static(适配器生命周期即进程生命周期)
|
||||
let leaked: &'static LarkClient = Box::leak(Box::new(client));
|
||||
Channel::builder(leaked, dispatcher)
|
||||
// client 已是 &'static(构造期一次性 leak);run() 重连重入只重建 Channel,
|
||||
// 不再重复 Box::leak(D1:防每次重入泄漏一份 LarkClient)
|
||||
Channel::builder(client, dispatcher)
|
||||
.policy(ChannelPolicy::default().require_mention(false))
|
||||
.on_message(move |msg| {
|
||||
let events = events_for_msg.clone();
|
||||
|
||||
Reference in New Issue
Block a user