Можно ли записать на канал с помощью функции http Handle? - PullRequest
0 голосов
/ 10 марта 2019

Я хочу передать значение в канал при возникновении http-запроса. Я получил этот код:

package main

import (
    "io"
    "net/http"
    "time"
)

var channel1 chan int

func main() {
    channel1 := make(chan int)
    go func() {
        select {
        case <-channel1:
            fmt.Println("Channel1")
        case <-time.After(time.Second * 100):
            fmt.Println("Timeout")
        }
    }()

    http.HandleFunc("/", handleMain)
    http.ListenAndServe("localhost:8080", nil)
}

func handleMain(w http.ResponseWriter, r *http.Request) {
    channel1 <- 1
    io.WriteString(w, "Hello from a HandleFunc!")
}

Это останавливается на channel1 <-1, когда я выполняю свой запрос к "/"почему так и как я могу добиться того, чего хочу? </p>

Ответы [ 2 ]

1 голос
/ 10 марта 2019

Да, это возможно.Следует учитывать жизненный цикл данных, которые вы отправляете на канал.В настоящее время канал не буферизован, поэтому для отправки:

channel1 <- 1

требуется получение:

case <-channel1:

Что означает, что запись будетставить в очередь и блокировать, пока они не будут готовы к обработке.Проблема заключается в том, что, как только будет получен прием, обработчик HTTP завершит работу, а 200 предложит клиенту, что операция прошла OK и прошла успешно.Проблема в том, что другая подпрограмма go с приемом может быть неполной, поскольку она выполняется одновременно с процедурой обработчика.Право собственности на данные было передано другой программе.Так что же произойдет, если другие ошибки выполнения, но клиент думает, что операция завершилась успешно?

Это становится более очевидным, если канал буферизируется, когда процедура обработчика http отправляет немедленно, а затем возвращает.Существует множество вариантов решения этой проблемы, но если ее не решить, это может привести к незначительной потере данных и логическим ошибкам.

0 голосов
/ 10 марта 2019

Понял, ошибка была в инициализации канала, я не должен писать channel1:=make(chan int), вместо этого использовал channel1=make(chan int), все работало!

...