Senior
Փաստաթղթերի թարմացումները գալիս են ծառայություն message Document { string Url = 1; // Փաստաթղթի URL- ը, նրա եզակի նույնականացուցիչ uint64 PubDate = 2; // հայտարարած հրապարակման ժամանակը uint64 FetchTime = 3; // այս փաստաթղթի թարմացման ստացման ժամանակը, կարող է դիտվել որպես տարբերակի նույնականացուցիչ։ Զույգ (Url, FetchTime) եզակի է։ string Text = 4; // փաստաթղթի տեքստը uint64 FirstFetchTime = 5; // սկզբում բացակայում է, պետք է լրացվի } Փաստաթղթերը կարող են գալ ցանկացած կարգով (ոչ այն կարգով, որով դրանք թարմացվել են), և հնարավոր է կրկնօրինակ հաղորդագրություններ: Ելքում անհրաժեշտ է ձևավորել նույն հաղորդագրությունները, բայց ուղղված հետևյալ կանոններին (այստեղ ամեն ինչ վերաբերում է նույն Url դաշտով խմբավորված փաստաթղթերին): Text և FetchTime դաշտերը պետք է լինեն այնպիսին, ինչպիսին եղել է մինչ այժմ ստացված ամենամեծ FetchTime-ով փաստաթղթում: PubDate դաշտը պետք է լինի այնպիսին, ինչպիսին եղել է ամենափոքր FetchTime-ով հաղորդագրությունում: FirstFetchTime դաշտը պետք է լինի ամենափոքր FetchTime-ով արժեքը: Այնպես որ, յուրաքանչյուր պահի մենք վերցնում ենք PubDate և FirstFetchTime- ը առաջին տարբերակից, որը մինչ այժմ ստացվել է (եթե դրանք դասավորենք FetchTime-ով), և Text- ը վերջինից: Կոդում այս ինտերֆեյսը կարող է իրականացվել այսպես: type Processor interface { Process(doc *Document) (*Document, error) } Այս կոդը կաշխատի ծառայությունում, որը կարդում է հաղորդագրություններ հերթից (Kafka կամ նման), և նաև գրում է արդյունքը հերթին: Եթե Process վերադարձնում է Null, ոչինչ չի գրանցվում հերթում:
sobes.tech AI
Պատասխան AI-ից
Для реализации интерфейса Processor в Go нужно хранить состояние по каждому Url, чтобы на каждый входящий документ обновлять агрегированное состояние и возвращать скорректированное сообщение.
Основная идея:
- Для каждого Url хранить:
- минимальный FetchTime (для PubDate и FirstFetchTime)
- максимальный FetchTime (для Text и FetchTime)
- PubDate, Text, FirstFetchTime, соответствующие этим минимальному и максимальному FetchTime
При получении нового документа:
- Если для Url нет записи — создать с данными из документа
- Иначе обновить минимальный и максимальный FetchTime и соответствующие поля при необходимости
- Вернуть агрегированный документ с нужными полями
Пример реализации:
import (
"errors"
"sync"
)
type Document struct {
Url string
PubDate uint64
FetchTime uint64
Text string
FirstFetchTime uint64
}
type Processor interface {
Process(doc *Document) (*Document, error)
}
type docState struct {
minFetchTime uint64
maxFetchTime uint64
pubDate uint64
text string
firstFetch uint64
}
type processorImpl struct {
mu sync.Mutex
state map[string]*docState
}
func NewProcessor() Processor {
return &processorImpl{
state: make(map[string]*docState),
}
}
func (p *processorImpl) Process(doc *Document) (*Document, error) {
if doc == nil {
return nil, errors.New("input document is nil")
}
p.mu.Lock()
defer p.mu.Unlock()
st, ok := p.state[doc.Url]
if !ok {
// первый документ для данного Url
p.state[doc.Url] = &docState{
minFetchTime: doc.FetchTime,
maxFetchTime: doc.FetchTime,
pubDate: doc.PubDate,
text: doc.Text,
firstFetch: doc.FetchTime,
}
return &Document{
Url: doc.Url,
PubDate: doc.PubDate,
FetchTime: doc.FetchTime,
Text: doc.Text,
FirstFetchTime: doc.FetchTime,
}, nil
}
updated := false
// Обновляем минимальный FetchTime и PubDate, FirstFetchTime
if doc.FetchTime < st.minFetchTime {
st.minFetchTime = doc.FetchTime
st.pubDate = doc.PubDate
st.firstFetch = doc.FetchTime
updated = true
}
// Обновляем максимальный FetchTime и Text
if doc.FetchTime > st.maxFetchTime {
st.maxFetchTime = doc.FetchTime
st.text = doc.Text
updated = true
}
// Если пришло сообщение с FetchTime, который уже есть, но текст или PubDate отличаются,
// можно игнорировать, так как пара (Url, FetchTime) уникальна, либо обновлять по логике.
if !updated {
// Данные не изменились, можно вернуть nil, чтобы не писать в очередь
return nil, nil
}
return &Document{
Url: doc.Url,
PubDate: st.pubDate,
FetchTime: st.maxFetchTime,
Text: st.text,
FirstFetchTime: st.firstFetch,
}, nil
}
Таким образом, сервис будет поддерживать актуальное агрегированное состояние для каждого Url и возвращать скорректированные документы согласно правилам.