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: ако някой промени горните страници или имате мрежови проблеми, резултатът от горния код вече може да се различава :)