fix: improve message handling and bus closure logic for better reliability

This commit is contained in:
tong3jie 2026-03-13 17:17:27 +08:00
parent 41dff3b9b9
commit 334c08a27f
3 changed files with 70 additions and 61 deletions

View file

@ -251,9 +251,11 @@ func (al *AgentLoop) Run(ctx context.Context) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return nil return nil
case msg := <-al.bus.InboundChan(): case msg, ok := <-al.bus.InboundChan():
if !ok {
return nil
}
// Process message // Process message
func() {
// TODO: Re-enable media cleanup after inbound media is properly consumed by the agent. // TODO: Re-enable media cleanup after inbound media is properly consumed by the agent.
// Currently disabled because files are deleted before the LLM can access their content. // Currently disabled because files are deleted before the LLM can access their content.
// defer func() { // defer func() {
@ -306,8 +308,8 @@ func (al *AgentLoop) Run(ctx context.Context) error {
) )
} }
} }
}()
default: default:
time.Sleep(time.Second * 5)
} }
} }

View file

@ -88,11 +88,13 @@ func (mb *MessageBus) OutboundMediaChan() <-chan OutboundMediaMessage {
func (mb *MessageBus) Close() { func (mb *MessageBus) Close() {
mb.closeOnce.Do(func() { mb.closeOnce.Do(func() {
mb.closed.Store(true)
// notify all blocked publishers to exit // notify all blocked publishers to exit
close(mb.done) close(mb.done)
// because every publisher will check mb.closed before acquiring wg
// so we can be sure that new publishers will not be added new messages after this point
mb.closed.Store(true)
// wait for all ongoing Publish calls to finish, ensuring all messages have been sent to channels or exited // wait for all ongoing Publish calls to finish, ensuring all messages have been sent to channels or exited
mb.wg.Wait() mb.wg.Wait()

View file

@ -43,7 +43,11 @@ func TestHandleIncoming_DoesNotConsumeGenericCommandsLocally(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() defer cancel()
inbound, ok := messageBus.ConsumeInbound(ctx) select {
case <-ctx.Done():
t.Fatal("timeout waiting for message to be forwarded")
return
case inbound, ok := <-messageBus.InboundChan():
if !ok { if !ok {
t.Fatal("expected inbound message to be forwarded") t.Fatal("expected inbound message to be forwarded")
} }
@ -54,3 +58,4 @@ func TestHandleIncoming_DoesNotConsumeGenericCommandsLocally(t *testing.T) {
t.Fatalf("content=%q", inbound.Content) t.Fatalf("content=%q", inbound.Content)
} }
} }
}