Журнал: индекс пакетов-ответов ИШ одним проходом (кэш 3 с), поиск по номерам поручений в памяти
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
@@ -210,25 +210,14 @@ func findOrderResponses(contrDID string) []orderResponse {
|
|||||||
if contrDID == "" {
|
if contrDID == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
entries, err := os.ReadDir(igwInboxDir)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
type rr struct {
|
type rr struct {
|
||||||
resp orderResponse
|
resp orderResponse
|
||||||
mt time.Time
|
mt time.Time
|
||||||
}
|
}
|
||||||
var tmp []rr
|
var tmp []rr
|
||||||
for _, e := range entries {
|
for _, pk := range pkgIndex() {
|
||||||
if !e.IsDir() {
|
dir, body, mt := pk.dir, pk.body, pk.mt
|
||||||
continue
|
if !strings.Contains(body, contrDID) {
|
||||||
}
|
|
||||||
dir := e.Name()
|
|
||||||
if strings.HasPrefix(dir, "#") || dir == "INBOX" { // наши M2M-пакеты — не ответ
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
body, mt := readPkgText(filepath.Join(igwInboxDir, dir))
|
|
||||||
if body == "" || !strings.Contains(body, contrDID) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
kind, done := orderRespKind(dir, body)
|
kind, done := orderRespKind(dir, body)
|
||||||
@@ -311,6 +300,49 @@ func collectOrderResponseRaw(contrDID string) []respFile {
|
|||||||
|
|
||||||
// readPkgText собирает текст всех документов пакета: распакованные xml/htm/rpt и
|
// readPkgText собирает текст всех документов пакета: распакованные xml/htm/rpt и
|
||||||
// содержимое вложенных zip (декодирует windows-1251). Возвращает текст и время.
|
// содержимое вложенных zip (декодирует windows-1251). Возвращает текст и время.
|
||||||
|
// pkgIndex — все пакеты-ответы во входящем каталоге ИШ с их текстом, одним проходом и с
|
||||||
|
// коротким кэшем: поиск ответов по номерам поручений идёт по памяти, а не по диску на
|
||||||
|
// каждый номер (сотни номеров × две тысячи каталогов давали сотни миллисекунд на страницу).
|
||||||
|
type pkgIndexEntry struct {
|
||||||
|
dir, body string
|
||||||
|
mt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkgIndexCache = struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
at time.Time
|
||||||
|
list []pkgIndexEntry
|
||||||
|
}{}
|
||||||
|
|
||||||
|
func pkgIndex() []pkgIndexEntry {
|
||||||
|
pkgIndexCache.mu.Lock()
|
||||||
|
defer pkgIndexCache.mu.Unlock()
|
||||||
|
if pkgIndexCache.list != nil && time.Since(pkgIndexCache.at) < 3*time.Second {
|
||||||
|
return pkgIndexCache.list
|
||||||
|
}
|
||||||
|
entries, err := os.ReadDir(igwInboxDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
list := make([]pkgIndexEntry, 0, len(entries))
|
||||||
|
for _, e := range entries {
|
||||||
|
if !e.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dir := e.Name()
|
||||||
|
if strings.HasPrefix(dir, "#") || dir == "INBOX" { // наши M2M-пакеты — не ответ
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
body, mt := readPkgText(filepath.Join(igwInboxDir, dir))
|
||||||
|
if body == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list = append(list, pkgIndexEntry{dir: dir, body: body, mt: mt})
|
||||||
|
}
|
||||||
|
pkgIndexCache.list, pkgIndexCache.at = list, time.Now()
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
// pkgTextCache — разобранный текст пакетов ИШ по каталогу: пакет после получения не меняется,
|
// pkgTextCache — разобранный текст пакетов ИШ по каталогу: пакет после получения не меняется,
|
||||||
// поэтому перечитывать его файлы при каждом обходе журнала незачем. Ключ проверки — время
|
// поэтому перечитывать его файлы при каждом обходе журнала незачем. Ключ проверки — время
|
||||||
// изменения каталога пакета и число файлов в нём.
|
// изменения каталога пакета и число файлов в нём.
|
||||||
|
|||||||
Reference in New Issue
Block a user