Георги обнови решението на 11.12.2014 06:54 (преди над 3 години)
+package main
+
+import (
+ "bytes"
+ "errors"
+ "net/http"
+ "sync/atomic"
+ "time"
+)
+
+type Helper struct {
+ Workers int32
+ MaxWorkers int
+ Result string
+ Queue []string
+}
+
+func (h Helper) AddWorker() {
+ atomic.AddInt32(&h.Workers, 1)
+}
+
+func (h Helper) ReleaseWorker() {
+ atomic.AddInt32(&h.Workers, -1)
+}
+
+func doWork(callback func(string) bool, h* Helper) {
+ for len(h.Queue) > 0 && h.Workers < int32(h.MaxWorkers) {
+ if len(h.Result) == 0 {
+ h.AddWorker()
+ elemIndex := len(h.Queue) - 1
+ go func(url string) {
+ defer h.ReleaseWorker()
+ timeout := time.Duration(3 * time.Second)
+ client := http.Client{
+ Timeout: timeout,
+ }
+ content, err := client.Get(url) // Fetch the URL.
+ if err != nil || content.StatusCode < 200 || content.StatusCode >= 300 {
+ return
+ }
+ buf := new(bytes.Buffer)
+ buf.ReadFrom(content.Body)
+ s := buf.String()
+ if callback(s) {
+ h.Result = url
+ }
+ }(h.Queue[elemIndex])
+ h.Queue = h.Queue[:elemIndex]
+ } else {
+ return
+ }
+ }
+}
+
+func RepeateDoWork(callback func(string) bool, h Helper) (string, error) {
+ for len(h.Queue) > 0 {
+ doWork(callback, &h)
+ if len(h.Result) > 0 {
+ return h.Result, nil
+ }
+ }
+ for h.Workers != 0 && len(h.Result) == 0 {
+ }
+ if len(h.Result) > 0 {
+ return h.Result, nil
+ }
+ return "", errors.New("Stopped listening for urls")
+}
+
+func SeekAndDestroy(callback func(string) bool,
+ chunkedUrlsToCheck <-chan []string,
+ workersCount int) (string, error) {
+
+ if workersCount <= 0 {
+ return "", errors.New("workersCount is not positive")
+ }
+ if chunkedUrlsToCheck == nil {
+ return "", errors.New("chunkedUrlsToCheck is not initialized")
+ }
+
+ h := Helper{0, workersCount, "", make([]string, 0, workersCount)}
+ for {
+ select {
+ case urls, isOk := <-chunkedUrlsToCheck:
+ if !isOk {
+ return RepeateDoWork(callback, h)
+ }
+ h.Queue = append(h.Queue, urls...)
+ doWork(callback, &h)
+ if len(h.Result) > 0 {
+ return h.Result, nil
+ }
+ case <-time.After(15 * time.Second):
+ return RepeateDoWork(callback, h)
+ }
+ }
+}
+
+func main() {
+}
Махни main()-а :)
Също така, помисли дали връщаш успешно намерения резултат в първия възможен момент