Gate pedigree behind a dog id set in settings
The pedigree view is now opt-in and tied to your own dog rather than an
always-present free-text search. Add the dog's SKK chip or registration
number in Settings (it rides the synced profile alongside name and
birthday); the 🌳 button stays hidden until one is set, then opens the
page and loads that dog's ancestry directly.
Make repeat opens cheap: memoise the id->hundid resolution server-side so
a cached tree is served without contacting SKK at all, and mirror the
finished tree in localStorage so the page paints instantly and shows the
last-known tree offline.
Adds config.pedigree_id (with an in-place migration for existing DBs).
This commit is contained in:
+32
-1
@@ -581,10 +581,28 @@ type pedManager struct {
|
||||
|
||||
mu sync.Mutex
|
||||
jobs map[string]*pedJob // keyed by hundid (coalesces duplicate lookups)
|
||||
|
||||
resolveMu sync.Mutex
|
||||
resolved map[string]string // query -> hundid, so a cache hit skips SKK entirely
|
||||
}
|
||||
|
||||
func newPedManager(db *sql.DB) *pedManager {
|
||||
return &pedManager{db: db, jobs: map[string]*pedJob{}}
|
||||
return &pedManager{db: db, jobs: map[string]*pedJob{}, resolved: map[string]string{}}
|
||||
}
|
||||
|
||||
func (m *pedManager) rememberResolve(q, hundid string) {
|
||||
if q == "" || hundid == "" {
|
||||
return
|
||||
}
|
||||
m.resolveMu.Lock()
|
||||
m.resolved[q] = hundid
|
||||
m.resolveMu.Unlock()
|
||||
}
|
||||
|
||||
func (m *pedManager) resolvedHundid(q string) string {
|
||||
m.resolveMu.Lock()
|
||||
defer m.resolveMu.Unlock()
|
||||
return m.resolved[q]
|
||||
}
|
||||
|
||||
func (m *pedManager) activeCount() int {
|
||||
@@ -751,6 +769,18 @@ func (m *pedManager) handleLookup(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Fast path: if we've resolved this query before and its tree is cached, serve
|
||||
// it without contacting SKK at all (repeat opens of your own dog's pedigree).
|
||||
if hundid := m.resolvedHundid(q); hundid != "" {
|
||||
if subj, nodes, ok := m.cached(hundid); ok {
|
||||
writeJSON(w, pedLookupResponse{
|
||||
Status: "done", Hundid: subj.Hundid, Subject: &subj,
|
||||
Generations: maxGenerations(nodes), Nodes: nodes,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
client, err := newSKKClient()
|
||||
if err != nil {
|
||||
http.Error(w, "server error", http.StatusInternalServerError)
|
||||
@@ -776,6 +806,7 @@ func (m *pedManager) handleLookup(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
subject := rowToSubject(rows[0])
|
||||
m.rememberResolve(q, subject.Hundid)
|
||||
|
||||
if subj, nodes, ok := m.cached(subject.Hundid); ok {
|
||||
writeJSON(w, pedLookupResponse{
|
||||
|
||||
Reference in New Issue
Block a user