ЛК: портфель ДЕПО «для всех клиентов» — одно соединение и один запрос к 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:
fontvielle
2026-10-23 14:45:16 +03:00
parent 21d5f33394
commit a0ffbfa721
10 changed files with 377 additions and 33 deletions
+31
View File
@@ -2,6 +2,7 @@ package lkgateway
import (
"context"
"database/sql"
"fmt"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/lkgateway/fsql"
"strings"
@@ -65,6 +66,11 @@ func depoClientPositions(ctx context.Context, s FancyMSSQLSettings, contract str
return nil, err
}
defer conn.Close()
return depoClientPositionsDB(ctx, conn, contract)
}
// depoClientPositionsDB — то же на открытом соединении (заполнение портфеля в ЛК: одно соединение на проход).
func depoClientPositionsDB(ctx context.Context, conn *sql.DB, contract string) ([]DepoPosition, error) {
cctx, cancel := context.WithTimeout(ctx, 25*time.Second)
defer cancel()
@@ -73,6 +79,31 @@ func depoClientPositions(ctx context.Context, s FancyMSSQLSettings, contract str
if err != nil {
return nil, err
}
return depoScanPositions(rows)
}
// depoAllPositions — остатки всех клиентов одним запросом (заполнение портфеля «для всех клиентов»),
// по портфелю (PORT_NUM без пробелов по краям).
func depoAllPositions(ctx context.Context, conn *sql.DB) (map[string][]DepoPosition, error) {
cctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()
rows, err := conn.QueryContext(cctx, fsql.Dp03)
if err != nil {
return nil, err
}
pos, err := depoScanPositions(rows)
if err != nil {
return nil, err
}
out := map[string][]DepoPosition{}
for _, p := range pos {
k := strings.TrimSpace(p.Contract)
out[k] = append(out[k], p)
}
return out, nil
}
func depoScanPositions(rows *sql.Rows) ([]DepoPosition, error) {
defer rows.Close()
var out []DepoPosition
for rows.Next() {