chat gets its own core connection, so a turn stops blocking every page (V-638)
ipc.Client serialises every call on one mutex, and mavweb routed 28 handlers plus /api/chat through the shared client. A turn is bounded only by phraser.timeout, 60s in deploy, so a page load behind one could wait that long. /models already had its own connection for this reason. Chat gets the third one. A failed dial logs and falls back to the shared client, which is how it behaved before. /api/ptt needs nothing here: it proxies to the voice port and never touches this client. A connection pool inside ipc.Client is the general form and stays unbuilt until a second module is measured queueing.
This commit is contained in:
+19
-1
@@ -58,6 +58,12 @@ func main() {
|
|||||||
// mutex, so sharing the connection would freeze every other page for the
|
// mutex, so sharing the connection would freeze every other page for the
|
||||||
// length of the load. See handleModels.
|
// length of the load. See handleModels.
|
||||||
var swapConn modelController
|
var swapConn modelController
|
||||||
|
// turnConn — a third connection, for POST /api/chat and nothing else, for
|
||||||
|
// the same reason /models has one (V-638). A chat turn routes, phrases and
|
||||||
|
// may act, bounded only by phraser.timeout at 60s, and every other handler
|
||||||
|
// on this server queues behind it on the shared client's one mutex. Nil ⇒
|
||||||
|
// chat shares the main connection, which is how it behaved before.
|
||||||
|
var turnConn ipc.CoreAPI
|
||||||
if *coreSock != "" {
|
if *coreSock != "" {
|
||||||
c, err := ipc.DialWait(*coreSock, 60*time.Second)
|
c, err := ipc.DialWait(*coreSock, 60*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -71,6 +77,12 @@ func main() {
|
|||||||
defer sc.Close()
|
defer sc.Close()
|
||||||
swapConn = sc
|
swapConn = sc
|
||||||
}
|
}
|
||||||
|
if tc, err := ipc.Dial(*coreSock); err != nil {
|
||||||
|
log.Printf("chat: third core connection failed (%v) — /api/chat will share the main one and a turn will block the other pages", err)
|
||||||
|
} else {
|
||||||
|
defer tc.Close()
|
||||||
|
turnConn = tc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// stepUpSession stays nil unless the passkey endpoints are wired below — it
|
// stepUpSession stays nil unless the passkey endpoints are wired below — it
|
||||||
@@ -208,7 +220,13 @@ func main() {
|
|||||||
// decides how every utterance is routed and how every reply is worded.
|
// decides how every utterance is routed and how every reply is worded.
|
||||||
mux.HandleFunc("/tools", gatedPage(handleTools))
|
mux.HandleFunc("/tools", gatedPage(handleTools))
|
||||||
mux.HandleFunc("/routines", gatedPage(handleRoutines))
|
mux.HandleFunc("/routines", gatedPage(handleRoutines))
|
||||||
mux.HandleFunc("/api/chat", gatedPage(handleChatAPI))
|
mux.HandleFunc("/api/chat", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
c := turnConn
|
||||||
|
if c == nil {
|
||||||
|
c = core
|
||||||
|
}
|
||||||
|
handleChatAPI(w, r, c, stepUpSession, *requireStepUp)
|
||||||
|
})
|
||||||
mux.HandleFunc("/api/revert", gatedPage(handleRevert))
|
mux.HandleFunc("/api/revert", gatedPage(handleRevert))
|
||||||
mux.HandleFunc("/api/correct", gatedPage(handleCorrectAPI))
|
mux.HandleFunc("/api/correct", gatedPage(handleCorrectAPI))
|
||||||
mux.HandleFunc("/models", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/models", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
Reference in New Issue
Block a user