Катя обнови решението на 10.11.2015 02:37 (преди над 2 години)
+package main
+
+import (
+ "strconv"
+ "strings"
+ "time"
+)
+
+func OrderedLogDrainer(logs chan (chan string)) (result chan string) {
+ result = make(chan string, 100)
+ m := make(map[int]chan string)
+ go func() {
+ var i = 0
+ for {
+ log, logsOpened := <-logs
+ if !logsOpened {
+ break
+ }
+ i += 1
+ m[i] = make(chan string, 100)
+ go func(num int) {
+ for {
+ logItem, logOpened := <-log
+ if !logOpened {
+ close(m[num])
+ break
+ }
+ lineContents := []string{strconv.Itoa(num), logItem}
+ var modifiedItem string = strings.Join(lineContents, "\t")
+ m[num] <- modifiedItem
+ }
+ }(i)
+ }
+ }()
+
+ go func() {
+ num := 1
+ maxTries := 3
+ for {
+ ch, ok := m[num]
+ if ok {
+ for {
+ logItem, logOpened := <-ch
+ if logOpened {
+ result <- logItem
+ } else {
+ num += 1
+ break
+ }
+ }
+ } else {
+ if maxTries > 0 {
+ time.Sleep(10 * time.Millisecond)
+ maxTries -= 1
+ } else {
+ break
+ }
+ }
+ }
+ close(result)
+ }()
+ return result
+}
Това ще работи в повечето случаи, но имаш потенциален race condition при достъп до m
. Предполагам знаеш, щом имаш maxTries
и time.Sleep()
.