Fix Remote speech stalls after pause and early completion

This commit is contained in:
ak47 committed 2026-11-06 22:11:29 -05:00
1 parent 6867d901b2
commit 19b789ef5c
6 files changed
+131 -30

No files matched your search

+26 -13
View File
@@ -38,6 +38,29 @@ func (client *Client) speak_and_wait_locked(ctx context.Context, speak func() er
}
}
}()
// Notifications can precede the SPEAK queue acknowledgement. Handle them
// while reading command replies too, or an early END/CANCEL is lost and
// this owner waits forever while later remote utterances queue behind it.
started, completed := false, false
var completion error
handle := func(event reply) {
if completed {
return
}
switch event.code {
case 701:
if !started && ctx.Err() == nil && began != nil {
began()
}
started = true
case 702:
completed, completion = true, ctx.Err()
case 703:
completed, completion = true, context.Canceled
}
}
client.notification = handle
defer func() { client.notification = nil }()
if err := speak(); err != nil {
return err
}
@@ -61,24 +84,14 @@ func (client *Client) speak_and_wait_locked(ctx context.Context, speak func() er
<-done
}
}()
started := false
for {
for !completed {
event, err := readReply(client.reader)
if err != nil {
_ = conn.Close()
client.conn, client.reader = nil, nil
return errors.Join(ctx.Err(), err)
}
switch event.code {
case 701:
if !started && ctx.Err() == nil && began != nil {
began()
}
started = true
case 702:
return ctx.Err()
case 703:
return context.Canceled
}
handle(event)
}
return errors.Join(ctx.Err(), completion)
}