mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-20 17:07:59 +00:00
feat(webui): scroll-paged record table, pool metrics, probe-aware health tags
Front-end half of the on-demand log loading plus the observability for the two
new scheduling mechanisms.
Records table:
* the first screen comes from the dashboard poll, and an IntersectionObserver
sentinel below the last row pulls the next page from /api/stats/records as
the user scrolls.
* rendered rows are capped at RECS_MAX_DOM=1000 (oldest rendered rows are
dropped) so a long scroll cannot grow the DOM without bound, with a "back
to newest" button to reset cheaply.
* releaseRecords() drops the buffer, disconnects the observer and aborts the
in-flight fetch (AbortController) on tab switch, on key-filter change and
on pagehide/beforeunload — leaving the page releases everything at once.
* the poll no longer rebuilds the table once extra pages are loaded, so the
5s refresh cannot throw away scrolled history.
* when the server reports replay_partial, the filter row states that the
aggregates cover the recent audit tail and points at CSV for full history.
Adapters page shows each pool as created/max plus in_use/idle and the live
grow/shrink steps, with the sizing rule in the hover text.
Priority page health tags now distinguish cooling / probe-ready / probing
instead of a flat "cooling", and the tooltip spells out when the window opened,
when the single probe is allowed through and when the slot clears completely.
core.AutoSlotState carries cooldown_from / probe_after / probing / probeable to
feed this.
This commit is contained in:
@ -26,12 +26,12 @@ import (
|
||||
// request paths look keys up concurrently; the AUTO chain itself is swapped
|
||||
// atomically and needs no lock.
|
||||
type Core struct {
|
||||
mu sync.Mutex
|
||||
cfg *config.Config
|
||||
vm *lua.VM
|
||||
store *config.Store
|
||||
scheduler *scheduler.Scheduler
|
||||
registry *provider.Registry
|
||||
mu sync.Mutex
|
||||
cfg *config.Config
|
||||
vm *lua.VM
|
||||
store *config.Store
|
||||
scheduler *scheduler.Scheduler
|
||||
registry *provider.Registry
|
||||
autoChain atomic.Pointer[scheduler.Chain] // chat AUTO chain
|
||||
autoImageChain atomic.Pointer[scheduler.Chain] // image-generation AUTO chain
|
||||
}
|
||||
@ -565,6 +565,16 @@ type AutoSlotState struct {
|
||||
FailCount int64 `json:"fail_count"`
|
||||
CooldownUntil int64 `json:"cooldown_until"`
|
||||
Cooling bool `json:"cooling"`
|
||||
// CooldownFrom is when the current cooldown window opened and ProbeAfter is
|
||||
// its midpoint: from ProbeAfter on, a single probe request is allowed
|
||||
// through so a recovered upstream does not have to sit out the rest of the
|
||||
// window. Probing reports whether such a probe is in flight right now.
|
||||
CooldownFrom int64 `json:"cooldown_from"`
|
||||
ProbeAfter int64 `json:"probe_after"`
|
||||
Probing bool `json:"probing"`
|
||||
// Probeable marks a cooling slot that is past its midpoint, i.e. the next
|
||||
// AUTO request may use it as a probe.
|
||||
Probeable bool `json:"probeable"`
|
||||
}
|
||||
|
||||
// AutoSlotStates returns per-slot health for every slot of the current chain.
|
||||
@ -582,6 +592,7 @@ func (c *Core) AutoSlotStates() []AutoSlotState {
|
||||
continue
|
||||
}
|
||||
pref, fail, until := pp.ModelHealthInfo(sl.Model)
|
||||
from, probeAfter, probing := pp.ModelProbeInfo(sl.Model)
|
||||
out = append(out, AutoSlotState{
|
||||
Model: sl.Model,
|
||||
Source: sl.Source,
|
||||
@ -589,6 +600,10 @@ func (c *Core) AutoSlotStates() []AutoSlotState {
|
||||
FailCount: fail,
|
||||
CooldownUntil: until,
|
||||
Cooling: until > now,
|
||||
CooldownFrom: from,
|
||||
ProbeAfter: probeAfter,
|
||||
Probing: probing,
|
||||
Probeable: until > now && probeAfter > 0 && now >= probeAfter,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -740,4 +755,4 @@ func (c *Core) Close() {
|
||||
if c.vm != nil {
|
||||
c.vm.Stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user