Concurrent Crawl with Worker Pool
Worker pool bilan concurrent crawl
Sahifalarni birma-bir, ketma-ket kezish sekin: har bir sahifani olish vaqt talab qiladi, va bu vaqtning katta qismi kutishda o'tadi. Concurrency Fundamentals kursidagi worker pool naqshi shu yerda o'z o'rnini topadi — bir nechta "ishchi" goroutina sahifalarni bir vaqtda qayta ishlaydi.
Bu yerdagi qiyinchilik — Worker Pools darsidagi misoldan farqli o'laroq, vazifalar soni oldindan ma'lum emas: har bir sahifa yangi havolalar (yangi vazifalar) hosil qilishi mumkin. Yechim — vazifalar kanaliga yangi topilgan havolalarni ham qaytadan yuborish, va sync.WaitGroupni har bir yangi vazifa uchun oshirib borish:
worker := func() {
for url := range jobs {
if !visited.MarkVisited(url) {
wg.Done()
continue
}
html, err := FetchPage(pages, url)
if err == nil {
// natijani saqlash...
links := ExtractLinks(html)
wg.Add(len(links))
for _, link := range links {
jobs <- link
}
}
wg.Done()
}
}Muhim naqsh: har safar jobsga yangi URL yuborilishidan oldin wg.Add(1) (yoki bir nechtasi uchun wg.Add(len(links))) chaqiriladi, va har bir vazifa tugaganda (o'tkazib yuborilgan bo'lsa ham) wg.Done() chaqiriladi. Bu — "hali qancha ish kutilyapti" hisobini har doim to'g'ri saqlaydi, shuning uchun wg.Wait() barcha sahifalar (va ulardan topilgan barcha havolalar) qayta ishlanganda aniq tugaydi. VisitedSetning MarkVisited metodi bu yerda sync.Mutex bilan himoyalangan bo'lishi shart — bir nechta worker bir vaqtda unga murojaat qiladi.
>_ Exercise
Berilgan VisitedSetga mu sync.Mutex maydonini qo'shib, MarkVisitedni Mutex bilan himoyalang. CrawlConcurrent(pages map[string]string, start string, numWorkers int) []string funksiyasini yozing: numWorkers ta worker goroutina ishga tushiring, ular buferlangan jobs kanalidan URL oladi, ko'rilmagan bo'lsa uni oladi, natijalar slice'iga (Mutex bilan himoyalangan) qo'shadi, va topilgan havolalarni qayta jobsga yuboradi (wg.Add/wg.Done bilan to'g'ri hisoblab). Boshlang'ich URL bilan boshlab, wg.Wait()dan keyin natijalarni saralab qaytaring.
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Dinamik ravishda o'sadigan vazifalar (crawler kabi) uchun worker pool naqshi: yangi topilgan ishlarni bir xil kanalga qaytadan yuborish, va WaitGroup hisobini har bir yangi vazifa qo'shilishidan oldin oshirish. VisitedSetni Mutex bilan himoyalash — bir nechta worker bir vaqtda unga murojaat qilganda to'g'rilikni kafolatlaydi.
NEXT UP
Depth Limiting and Rate Limiting
$ go run main.go
Kodingizni ishga tushiring