Решение на Concurrent Crawling от Александър Ваканин

Обратно към всички решения

Към профила на Александър Ваканин

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 4 успешни тест(а)
  • 7 неуспешни тест(а)

Код

package main
import (
"time"
"fmt"
"net/http"
"io/ioutil"
)
var err = fmt.Errorf("ERROR")
func SeekAndDestroy(callback func(string) bool, chunkedUrlsToCheck <-chan []string, workersCount int) (string, error) {
var result string
if chunkedUrlsToCheck == nil || workersCount <= 0 {
return result, err
}
for {
select {
case urls := <-chunkedUrlsToCheck:
go func(res *string) string {
check(callback, urls, res, workersCount - 1)
return *res
}(&result)
case <- time.After(15 * time.Second):
return result, err
}
}
return result, nil
}
func check(callback func(string) bool, urls []string, result *string, count int) bool {
if count <= 0 {
return false
}
for _, url := range urls {
response, err := http.Get(url)
if err != nil {
fmt.Printf("%s", err)
return false
/*} else if response.Status == false {
fmt.Printf("invalid url\n")*/
} else {
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Printf("%s", err)
return false
}
str := CToGoString(contents[:])
if callback(str) {
*result = url
return true
}
}
}
return false
}
func CToGoString(c []byte) string {
n := -1
for i, b := range c {
if b == 0 {
break
}
n = i
}
return string(c[:n+1])
}

Лог от изпълнението

[/tmp/go-build200079035/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWithNegativeWorkersCount -test.timeout=120s]
PASS
ok  	_/tmp/d20150111-16649-igpjpk	0.005s
[/tmp/go-build733960792/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWithZeroWorkersCount -test.timeout=120s]
PASS
ok  	_/tmp/d20150111-16649-igpjpk	0.007s
[/tmp/go-build623143522/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWithInvalidCallback -test.timeout=120s]
--- FAIL: TestWithInvalidCallback-2 (1.00 seconds)
	solution_test.go:43: Test exceeded allowed time of 1 seconds: parameter errors should be immediately returned (callback is nil)
FAIL
exit status 1
FAIL	_/tmp/d20150111-16649-igpjpk	1.007s
[/tmp/go-build081779132/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWithNilChannel -test.timeout=120s]
PASS
ok  	_/tmp/d20150111-16649-igpjpk	0.009s
[/tmp/go-build677408774/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWithClosedChannelWhenStarting -test.timeout=120s]
--- FAIL: TestWithClosedChannelWhenStarting-2 (1.00 seconds)
	solution_test.go:43: Test exceeded allowed time of 1 seconds: parameter errors should be immediately returned (the urls channel was closed)
FAIL
exit status 1
FAIL	_/tmp/d20150111-16649-igpjpk	1.015s
[/tmp/go-build145518571/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWithClosedChannelMidway -test.timeout=120s]
--- FAIL: TestWithClosedChannelMidway-2 (7.00 seconds)
	solution_test.go:43: Test exceeded allowed time of 7 seconds: the urls channel was closed after 5 seconds
FAIL
exit status 1
FAIL	_/tmp/d20150111-16649-igpjpk	7.016s
[/tmp/go-build801205093/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWhetherGlobalTimeoutIsHandled -test.timeout=120s]
PASS
ok  	_/tmp/d20150111-16649-igpjpk	15.007s
[/tmp/go-build913384017/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestWithLoremIpsum -test.timeout=120s]
--- FAIL: TestWithLoremIpsum-2 (4.00 seconds)
	solution_test.go:43: Test exceeded allowed time of 4 seconds: Connecting to localhost should be pretty fast...
FAIL
exit status 1
FAIL	_/tmp/d20150111-16649-igpjpk	4.009s
[/tmp/go-build814308734/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestIfTimeoutAndErrorCodesAreHonoured -test.timeout=120s]
--- FAIL: TestIfTimeoutAndErrorCodesAreHonoured-2 (10.00 seconds)
	solution_test.go:43: Test exceeded allowed time of 10 seconds: This should have finished in approx. 8 seconds
FAIL
exit status 1
FAIL	_/tmp/d20150111-16649-igpjpk	10.006s
[/tmp/go-build257030972/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestRaceCondition -test.timeout=120s]
--- FAIL: TestRaceCondition-2 (5.00 seconds)
	solution_test.go:43: Test exceeded allowed time of 5 seconds: This should have finished in approx. 3 seconds
FAIL
exit status 1
FAIL	_/tmp/d20150111-16649-igpjpk	5.005s
[/tmp/go-build664488225/_/tmp/d20150111-16649-igpjpk/_test/d20150111-16649-igpjpk.test -test.run=TestCloseChannelBeforeFinish -test.timeout=120s]
--- FAIL: TestCloseChannelBeforeFinish-2 (3.00 seconds)
	solution_test.go:43: Test exceeded allowed time of 3 seconds: This should have finished in approx. 1 second
FAIL
exit status 1
FAIL	_/tmp/d20150111-16649-igpjpk	3.011s

История (1 версия и 0 коментара)

Александър обнови решението на 11.12.2014 16:57 (преди над 3 години)

+package main
+
+import (
+ "time"
+ "fmt"
+ "net/http"
+ "io/ioutil"
+)
+
+var err = fmt.Errorf("ERROR")
+
+func SeekAndDestroy(callback func(string) bool, chunkedUrlsToCheck <-chan []string, workersCount int) (string, error) {
+ var result string
+
+ if chunkedUrlsToCheck == nil || workersCount <= 0 {
+ return result, err
+ }
+
+ for {
+ select {
+ case urls := <-chunkedUrlsToCheck:
+ go func(res *string) string {
+ check(callback, urls, res, workersCount - 1)
+ return *res
+ }(&result)
+ case <- time.After(15 * time.Second):
+ return result, err
+ }
+ }
+ return result, nil
+}
+
+func check(callback func(string) bool, urls []string, result *string, count int) bool {
+ if count <= 0 {
+ return false
+ }
+ for _, url := range urls {
+ response, err := http.Get(url)
+ if err != nil {
+ fmt.Printf("%s", err)
+ return false
+ /*} else if response.Status == false {
+ fmt.Printf("invalid url\n")*/
+ } else {
+ defer response.Body.Close()
+ contents, err := ioutil.ReadAll(response.Body)
+ if err != nil {
+ fmt.Printf("%s", err)
+ return false
+ }
+ str := CToGoString(contents[:])
+ if callback(str) {
+ *result = url
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func CToGoString(c []byte) string {
+ n := -1
+ for i, b := range c {
+ if b == 0 {
+ break
+ }
+ n = i
+ }
+ return string(c[:n+1])
+}