9p: split clunk into sync (Rerror) and async (fire-and-forget)
prompt, enqueue, ctl writes run async — they may block for an entire agent turn and don't benefit from Rerror. Everything else (disk I/O, state mutations, s/new) runs synchronously so errors surface as Rerror without holding the connection.
This commit is contained in:
parent
d326ca88f7
commit
81f7379fb6
|
|
@ -737,13 +737,29 @@ func (s *Server) clunk(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
||||||
}
|
}
|
||||||
cs.mu.Unlock()
|
cs.mu.Unlock()
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
if err := s.handleWrite(path, strings.TrimSpace(string(data))); err != nil {
|
input := strings.TrimSpace(string(data))
|
||||||
|
if s.isAsyncWrite(path) {
|
||||||
|
go s.handleWrite(path, input) //nolint:errcheck
|
||||||
|
} else if err := s.handleWrite(path, input); err != nil {
|
||||||
return errFcall(fc, err.Error())
|
return errFcall(fc, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &plan9.Fcall{Type: plan9.Rclunk, Tag: fc.Tag}
|
return &plan9.Fcall{Type: plan9.Rclunk, Tag: fc.Tag}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isAsyncWrite returns true for paths where writes may block (agent turns)
|
||||||
|
// and Rerror is not useful.
|
||||||
|
func (s *Server) isAsyncWrite(path string) bool {
|
||||||
|
if !strings.HasPrefix(path, "/s/") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch pathBase(path) {
|
||||||
|
case "prompt", "enqueue", "ctl":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) remove(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
func (s *Server) remove(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
||||||
cs.mu.Lock()
|
cs.mu.Lock()
|
||||||
f, ok := cs.fids[fc.Fid]
|
f, ok := cs.fids[fc.Fid]
|
||||||
|
|
@ -861,13 +877,10 @@ func (s *Server) handleWrite(path, input string) error {
|
||||||
|
|
||||||
switch fileName {
|
switch fileName {
|
||||||
case "prompt":
|
case "prompt":
|
||||||
// prompt blocks for the entire agent turn; run async.
|
sess.core.Submit(sess.ctx, input, publish)
|
||||||
go func() {
|
sess.mu.Lock()
|
||||||
sess.core.Submit(sess.ctx, input, publish)
|
sess.replyVers++
|
||||||
sess.mu.Lock()
|
sess.mu.Unlock()
|
||||||
sess.replyVers++
|
|
||||||
sess.mu.Unlock()
|
|
||||||
}()
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case "enqueue":
|
case "enqueue":
|
||||||
|
|
|
||||||
Reference in New Issue