ЛК: портфель ДЕПО «для всех клиентов» — одно соединение и один запрос к DEPO, свой цикл раз в 5 мин; итог в настройках свёрнут
На 9 после включения «для всех» (23.10.2026) каждый проход открывал по два соединения с DEPO на каждый из 1158 договоров — около 50 входов в MSSQL в секунду без перерыва, а проход шёл в цикле опроса заявок ЛК и задерживал его. - Остатки всех клиентов — одним запросом (fsql.Dp03), одно соединение с DEPO на проход; по списку — запрос по клиенту на том же соединении. На боевой DEPO: общий запрос 127 мс, совпадает с запросом по клиенту (58 договоров). - Свой цикл lkPortfolioLoop (здоровье «lk-portfolio»): по списку — каждые 10 с, для всех клиентов — раз в 5 мин. Опрос заявок ЛК больше не ждёт. - Проходы по очереди: фоновый и «Заполнить сейчас» не шлют один портфель дважды; принудительный проход пропускает отправленные за последнюю минуту. - ЛК не отвечает — проход прерывается; одна и та же ошибка отправки не повторяется в журнале каждый проход. Ошибка чтения DEPO снимается, когда портфель снова читается без изменений. - Настройки: итог (договоров, отправлено, нечего отправлять, с ошибкой), последние 5 отправок; договоры с ошибкой и все договоры — под раскрытием. «Отправлять нечего» — не ошибка (поле Nothing). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
@@ -4,7 +4,9 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLKPaperTypeAndPairs(t *testing.T) {
|
||||
@@ -36,6 +38,57 @@ func TestLKContractByAccount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Остатки общего запроса раскладываются по портфелям пар как в Dp01: совпадение или «портфель + пробел».
|
||||
func TestLKPortfolioByPort(t *testing.T) {
|
||||
all := map[string][]DepoPosition{
|
||||
"БР-1001 Гравс Геннадий": {{AccountNum: "ВТНКЦ01", ISIN: "RU2", SecurityName: "Б"}, {AccountNum: "ВТНКЦ01", ISIN: "RU1", SecurityName: "А"}},
|
||||
"БР-10011 Другой": {{AccountNum: "ВТНКЦ02", ISIN: "RU3", SecurityName: "В"}},
|
||||
"БР-7": {{AccountNum: "ВТНКЦ07", ISIN: "RU4", SecurityName: "Г"}},
|
||||
}
|
||||
by := lkPortfolioByPort(all, []lkPortfolioPair{{LK: "ДД-1", Depo: "БР-1001"}, {LK: "ДД-7", Depo: "БР-7"}, {LK: "ДД-9", Depo: "БР-9"}})
|
||||
if p := by["БР-1001"]; len(p) != 2 || p[0].ISIN != "RU1" || p[1].ISIN != "RU2" {
|
||||
t.Fatalf("БР-1001: %+v", p)
|
||||
}
|
||||
if len(by["БР-7"]) != 1 || len(by["БР-9"]) != 0 || len(by) != 2 {
|
||||
t.Fatalf("%+v", by)
|
||||
}
|
||||
}
|
||||
|
||||
// Итог заполнения: «нечего отправлять» — не ошибка, все договоры — под раскрытием.
|
||||
func TestLKPortfolioSummaryView(t *testing.T) {
|
||||
lkPortfolioState.Lock()
|
||||
saved := lkPortfolioState.m
|
||||
now := time.Now()
|
||||
lkPortfolioState.m = map[string]*LKPortfolioSyncState{
|
||||
"ДД-1": {LK: "ДД-1", Depo: "БР-1-1", CheckedAt: now, Nothing: lkPortfolioNothing([]string{"x"}), Skipped: []string{"x"}},
|
||||
"ДД-1006": {LK: "ДД-1006", Depo: "БР-1047", CheckedAt: now, PushedAt: now, Lines: 1},
|
||||
"ДД-1007": {LK: "ДД-1007", Depo: "БР-1048", CheckedAt: now, Err: "DEPO: i/o timeout"},
|
||||
"ДД-816": {LK: "ДД-816", Depo: "БР-859", CheckedAt: now, PushedAt: now, Lines: 3, manual: true},
|
||||
}
|
||||
lkPortfolioState.Unlock()
|
||||
defer func() { lkPortfolioState.Lock(); lkPortfolioState.m = saved; lkPortfolioState.Unlock() }()
|
||||
|
||||
sm := lkPortfolioSummary()
|
||||
if sm.Total != 3 || sm.Sent != 1 || sm.Nothing != 1 || sm.Errors != 1 || sm.Skipped != 1 || sm.Manual == nil || len(sm.Recent) != 1 {
|
||||
t.Fatalf("%+v", sm)
|
||||
}
|
||||
a, err := newAdmin()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
render(rec, a.setup, SetupData{page: nowPage("Настройка", "setup")})
|
||||
body := rec.Body.String()
|
||||
for _, want := range []string{"Итог заполнения", "Все договоры (3)", "Договоры с ошибкой (1)", "Последние обновления", "Заливка одному клиенту"} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Errorf("нет %q", want)
|
||||
}
|
||||
}
|
||||
if strings.Contains(body, "ошибка — отправлять нечего") {
|
||||
t.Error("«отправлять нечего» показано как ошибка")
|
||||
}
|
||||
}
|
||||
|
||||
// Маршруты карточки «Заполнение портфеля ДЕПО» зарегистрированы (29.09–22.10 их не было — 404).
|
||||
func TestLKPortfolioRoutes(t *testing.T) {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
Reference in New Issue
Block a user