Routes may share one lease (affinity = "route") and skip crossbar's queue (queue = false)

route.go gains Route.Affinity/Queue with PerRoute(), Queues() and affinity
validation (checkRoutes moved here; config.go calls it once). limiter.Track
counts a request without holding or refusing it; a release hands the slot to a
waiter only while in flight <= parallel. The proxy leases a PerRoute() route
under an empty fingerprint (the row keeps the real one) and uses Track when
Queues() is false.

Implemented by Ornith (OpenCode); owner review removed a release-on-first-flush
workaround for a race in the owner's given test (see implementer log).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 19:33:46 -07:00
co-authored by Claude Opus 5.5
parent 33fa61bedb
commit aea2eeae2c
8 changed files with 486 additions and 85 deletions
+89
View File
@@ -1,13 +1,41 @@
package config
import (
"fmt"
"regexp"
"sort"
"strings"
)
// templateName matches a route template: a valid route name ending in "-*".
var templateName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*-\*$`)
// routeName matches a route (or template) name: the pattern a concrete or template route key must
// match, so a name with '*' or an invalid prefix never resolves.
var routeName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
// Route is an ordered list of hosts to try, with an optional default model, the peers allowed to
// reach it, how its requests are placed (affinity), and whether crossbar queues them.
type Route struct {
Hosts []string `toml:"hosts"`
DefaultModel string `toml:"default_model"`
Peers []string `toml:"peers"`
Affinity string `toml:"affinity"` // "" or "conversation" (the default), or "route"
Queue *bool `toml:"queue"` // nil means true
}
// PerRoute reports affinity = "route": every request on the route (chat or control) shares one
// lease per model, so the route lives on one host.
func (r Route) PerRoute() bool {
return r.Affinity == "route"
}
// Queues reports whether the route's requests wait in (and can be refused by) crossbar's per-(host,
// model) queue; false only for queue = false, which leaves queueing to the client's own slot.
func (r Route) Queues() bool {
return r.Queue == nil || *r.Queue
}
// Route resolves a request route name: an exact entry wins; else the longest template
// "<prefix>-*" whose prefix (including the dash) starts name with a non-empty remainder;
// else ok is false. key is the config key that matched (the template's name for a template).
@@ -38,3 +66,64 @@ func (c *Config) Route(name string) (r Route, key string, ok bool) {
}
return best, bestKey, true
}
// checkRoutes validates and defaults one route's hosts, model, affinity and peers in a fixed order.
// A name that is neither a valid route nor a template, a missing or unknown host, a default model no
// host serves, an unrecognised affinity, or a peers list that breaks the identity contract each
// wins as the first error.
func (c *Config) checkRoutes(peersDefined map[string]bool, identityDefined bool) *Error {
if len(c.Routes) == 0 {
return &Error{Field: "routes", Msg: "at least one required"}
}
names := make([]string, 0, len(c.Routes))
for name := range c.Routes {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
r := c.Routes[name]
if !routeName.MatchString(name) && !templateName.MatchString(name) {
return &Error{Field: fmt.Sprintf("routes.%s", name), Msg: "must match [a-z0-9][a-z0-9-]*"}
}
hostsField := fmt.Sprintf("routes.%s.hosts", name)
if len(r.Hosts) == 0 {
return &Error{Field: hostsField, Msg: "at least one required"}
}
seen := make(map[string]bool, len(r.Hosts))
for _, h := range r.Hosts {
if seen[h] {
return &Error{Field: hostsField, Msg: "host listed twice"}
}
seen[h] = true
if _, ok := c.Hosts[h]; !ok {
return &Error{Field: hostsField, Msg: "unknown host"}
}
}
if r.DefaultModel != "" {
served := false
for _, h := range r.Hosts {
if _, ok := c.Hosts[h].Models[r.DefaultModel]; ok {
served = true
break
}
}
if !served {
return &Error{Field: fmt.Sprintf("routes.%s.default_model", name), Msg: "not served by any host in route"}
}
}
switch r.Affinity {
case "", "conversation", "route":
default:
return &Error{Field: fmt.Sprintf("routes.%s.affinity", name), Msg: `must be "conversation" or "route"`}
}
if e := checkPeers(name, r.Peers, peersDefined[name], identityDefined, c.Identity); e != nil {
return e
}
}
return nil
}