«Настройка» без 10-секундного ожидания: статистика npr.history по первичному ключу
Каждый рендер «Настройки» ждал /section службы bj-quikexport, а та считала min(ts) и count(*) за сутки по npr.history (18,5 млн строк, индекса по ts нет): 6 + 27 с на 28, срез по таймауту 10 с. Теперь начало истории — первая строка по id, строки за сутки/час — двоичный поиск по id (история только дописывается): ~45 мс. То же в /admin/npr/api/freshness. bj-server ждёт раздел QUIK-экспорта не дольше 3 с и иначе отдаёт последний удачный; прогрев версий, пользователей ЛК и раздела после запуска. «Обновления» перезагружают страницу, только если что-то изменилось. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -59,14 +60,33 @@ func quikExportDo(ctx context.Context, rc *RuntimeConfig, method, uri string, bo
|
||||
return quikExportHTTP.Do(req)
|
||||
}
|
||||
|
||||
// qxSection — последний ответ службы: страница «Настройка» не ждёт её дольше qxSectionWait, а отдаёт
|
||||
// последний удачный раздел (служба могла задуматься над статистикой базы).
|
||||
var qxSection struct {
|
||||
sync.Mutex
|
||||
v QuikExportView
|
||||
at time.Time
|
||||
ro bool
|
||||
}
|
||||
|
||||
const qxSectionWait = 3 * time.Second
|
||||
|
||||
func quikExportView(rc *RuntimeConfig, showRO bool) QuikExportView {
|
||||
uri := "/section"
|
||||
if showRO {
|
||||
uri += "?reveal_ro=1"
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), qxSectionWait)
|
||||
defer cancel()
|
||||
resp, err := quikExportDo(ctx, rc, http.MethodGet, uri, nil, "")
|
||||
if err != nil {
|
||||
qxSection.Lock()
|
||||
v, at, ro := qxSection.v, qxSection.at, qxSection.ro
|
||||
qxSection.Unlock()
|
||||
if !at.IsZero() && ro == showRO && time.Since(at) < 30*time.Minute {
|
||||
return v
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
b, rerr := io.ReadAll(io.LimitReader(resp.Body, 4<<20))
|
||||
resp.Body.Close()
|
||||
@@ -76,7 +96,11 @@ func quikExportView(rc *RuntimeConfig, showRO bool) QuikExportView {
|
||||
case resp.StatusCode != http.StatusOK:
|
||||
err = fmt.Errorf("служба ответила %d: %s", resp.StatusCode, strings.TrimSpace(string(b)))
|
||||
default:
|
||||
return QuikExportView{HTML: template.HTML(b), Ind: resp.Header.Get("X-BJ-Indicator")}
|
||||
v := QuikExportView{HTML: template.HTML(b), Ind: resp.Header.Get("X-BJ-Indicator")}
|
||||
qxSection.Lock()
|
||||
qxSection.v, qxSection.at, qxSection.ro = v, time.Now(), showRO
|
||||
qxSection.Unlock()
|
||||
return v
|
||||
}
|
||||
}
|
||||
return QuikExportView{Ind: "err", HTML: template.HTML(`<h1>QUIK — Экспорт биржевой информации</h1>`) + moduleMessage(
|
||||
|
||||
Reference in New Issue
Block a user