Убедитесь, что за один раз обрабатывается только один запрос, а другие входящие запросы отклоняются - PullRequest
2 голосов
/ 04 августа 2020

У меня есть горутина, назовем ее goProcessor, которая обрабатывает запросы, поступающие от других горутин.

goProcessor может обрабатывать только один запрос за раз. Если запрос, назовем его req2 , приходит, пока goProcessor все еще обрабатывает предыдущий запрос req1 , req2 должен быть отброшен и будет просто потерян.

Я реализовал такой logi c, используя небуферизованный канал и оператор select, но я не уверен, может ли быть более простой и элегантный способ sh того, что я хочу. Простой пример моего решения:

var c = make(chan string)

func main() {

    goRequest := func(request string, delay int) {
        time.Sleep(time.Duration(delay) * time.Second)
        fmt.Printf("Here I am request %v\n", request)
        select {
        case c <- request:
            fmt.Printf("%v sent\n", request)
        default:
            fmt.Printf("%v discarded\n", request)
        }
    }

    goProcessor := func() {
        for {
            msg := <-c
            fmt.Println("received", msg)
            time.Sleep(3 * time.Second)
            fmt.Println("processed", msg)
        }
    }

    go goRequest("First req", 1)
    go goRequest("Second req", 2)
    go goRequest("Third req", 5)
    go goProcessor()

    time.Sleep(10 * time.Second)

    fmt.Println("Main has finished")
}

1 Ответ

1 голос
/ 04 августа 2020

То, что вы сделали, прекрасно и чисто. Единственное, что вы могли бы упростить, это использовать for range в goProcessor(), например:

for msg := range c {
    // ...
}

, но кроме этого, это идиоматия c.

"TryLock" может пришло в голову использовать здесь. В стандартной библиотеке нет "TryLock" (для этого есть сторонние библиотеки ), но использовать его не проще и не более идиоматично c в вашем случае, вы должны проверить, TryLock() возвращает true, и надо его разблокировать. И вам по-прежнему нужен канал для отправки результатов в процессор, поэтому ваше решение будет проще и чище.

...