close (канал) используется для реализации паттерна наблюдателя - PullRequest
0 голосов
/ 17 сентября 2018

Мне нужно остановить HTTP-сервер по требованию, кроме вызова других функций, а также при получении сигнала "quit" в произвольном порядке.

В моей попытке реализовать что-то вроде шаблона наблюдателя , я нашел «удобным» создать канал (quit := make(chan struct{}), скажем, « subject », а затем на каждой из процедур « наблюдатели » прослушивают этот канал <-quit ожидание изменения для продолжения.

Способ, которым я запускаю все функции одновременно, - закрытие канала close(quit), не записывая в него, я пробовал это и пока работаю, ноИнтересно, есть ли какие-то минусы с этим подходом или есть лучшие / идиоматические способы реализации подобного поведения / паттерна.

package main

import (
    "log"
    "net/http"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup

    srv := &http.Server{Addr: ":8080"}

    wg.Add(1)
    go func() {
        log.Println(srv.ListenAndServe())
        wg.Done()
    }()

    quit := make(chan struct{})
    go func() {
        <-quit
        if err := srv.Close(); err != nil {
            log.Printf("HTTP server Shutdown: %v", err)
        }
    }()

    wg.Add(1)
    go func() {
        <-quit
        log.Println("just waiting 1")
        wg.Done()
    }()

    wg.Add(1)
    go func() {
        <-quit
        log.Println("just waiting 2")
        wg.Done()
    }()

    <-time.After(2 * time.Second)
    close(quit)
    wg.Wait()
}

https://play.golang.org/p/uIfMJfN6xQy

1 Ответ

0 голосов
/ 17 сентября 2018

Я бы сказал, что ваш путь достаточно хорош, но ему не хватает элегантности.

Вы можете реализовать требуемое поведение, используя sync.Cond:

https://golang.org/pkg/sync/#Cond
Как правильно использовать sync.Cond?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...