fix(feishu): decouple trigger ingest from the Lark WS dispatch thread (#208)

ChannelMessageEventBridge.onChannelMessage() ran synchronously on the Lark
SDK WebSocket dispatch thread; when the DB pool was saturated its ingest
query blocked that thread and subsequent messages were silently dropped.

- @Async moves trigger ingest onto the (vthread + SecurityContext-propagating)
  async executor, freeing the WS dispatch thread.
- Add a 10s timeout to the refreshTenantAccessToken() HTTP request, which
  previously had none.

Scope narrowed per review to only fix #208: the @mention alias learning and
session-id changes are dropped (to be raised as separate PRs), and dev's
existing message dedup is left untouched.

Closes #208
This commit is contained in:
倪程伟 2026-06-09 01:30:10 +08:00 committed by matevip
parent 94cf812207
commit 40a33e4ac7
2 changed files with 3 additions and 0 deletions

View File

@ -794,6 +794,7 @@ public class FeishuChannelAdapter extends AbstractChannelAdapter implements Stre
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiBase + "/open-apis/auth/v3/tenant_access_token/internal"))
.header("Content-Type", "application/json; charset=utf-8")
.timeout(Duration.ofSeconds(10))
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();

View File

@ -3,6 +3,7 @@ package vip.mate.trigger.dispatch;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import vip.mate.channel.event.ChannelMessageReceivedEvent;
import vip.mate.trigger.ingest.TriggerEventEnvelope;
@ -31,6 +32,7 @@ public class ChannelMessageEventBridge {
private final TriggerEventIngestService ingestService;
@Async
@EventListener
public void onChannelMessage(ChannelMessageReceivedEvent event) {
if (event == null) return;