Concurrent Crawling
- Краен срок:
- 11.12.2014 17:00
- Точки:
- 10
Срокът за предаване на решения е отминал
Нипишете функция SeekAndDestroy, която приема като аргументи: callback func(string) bool, chunkedUrlsToCheck <-chan []string, workersCount int и връща string, error.
Функцията трябва паралелно (с до workersCount горутини) да обходи подадените ѝ чрез urls адреси и да върне като резултат първия URL адрес, чието съдържание, подадено на callback, връща true.
Трябва да бъдат спазени следните условуя:
- Ако подадените параметри са грешни (пр. workersCountе неположително число или каналът не е инициализиран), функцията трябва веднага да върне грешка.
- Каналът urlsне трябва да бъде блокиран. Дори и по него да се получат повече отworkersCountадреси, те трябва да бъдат буферирани от функцията, така че каналът да остане отворен за писане.
- Функцията трябва да се опитва, ако има достатъчно "работа", да поддържа броят "работници" да бъде workersCount. Възможно е обаче по каналаurlsда се подадат по-малко на брой URL адреси от лимитът паралелни работнициworkersCount- тогава няма нужда да се създават idle workers.
- След като callbackфункцията върне позитивен резултат за някой от подадените поurlsадреси, функцията трябва да приключи веднага и да върне съответният адрес. Всички останали непроверени адреси трябва да се игнорират.
- Всеки HTTP request до подадените urlsтрябва да има timeout от 3 секунди.
- Ако някой HTTP request надвиши timeout времето или има грешка при зареждането (невалиден домейн, HTTP status != 2xx, etc.), съответният URL се счита за невалиден резултат.
- Ако каналът urlsбъде затворен или до 15 секунди никой от подадените URL адреси не отговаря на изискванията, функцията трябва да върне грешка.
Бонус точки ще бъдат давани на решенията, които не създават idle работници и чиито работници биват "убивани" максимално бързо след намерен резултат или глобален timeout (т.е. техните http заявки не се изчакват да приключат).
Пример:
urls := make(chan []string)
go func() {
    urls <- []string{"http://www.abv.bg", "http://www.dir.bg"}
    time.Sleep(5 * time.Second)
    urls <- []string{"http://www.google.com", "invalid.url....", "http://en.wikipedia.org/wiki/Lorem_ipsum"}
}()
callback := func(contents string) bool {
    return strings.Contains(contents, "Lorem ipsum")
}
result, _ := SeekAndDestroy(callback, urls, 3)
fmt.Println(result)
// Output: http://en.wikipedia.org/wiki/Lorem_ipsum
Disclaimer: ако някой промени горните страници или имате мрежови проблеми, резултатът от горния код вече може да се различава :)
