
Roman
15.08.2018
11:53:03
коллеги, у меня тут странное, и никогда мной доселе невиданное
у меня есть код:
func (s *Forwarder) listenTCP(addr string) error {
listener, err := net.Listen("tcp4", addr)
if err != nil {
return errors.Wrapf(err, "failed to listen tcp: %s", addr)
}
for {
conn, err := listener.Accept()
if err != nil {
errorsMetric.WithLabelValues("Accept", "tcp").Add(1)
return errors.Wrap(err, "failed to accept connection")
}
acceptedMetric.WithLabelValues("tcp").Add(1)
go checkAndForward(
conn.(*net.TCPConn),
s.Target,
s.Timeout,
s.HeaderLen,
s.ProxyHosts,
)
}
}
и время от времени он выдает мне ошибку в строке conn, err := listener.Accept()
accept tcp4 0.0.0.0:443: bad file descriptor
failed to accept connection
main.(*Forwarder).listenTCP
forwarder.go:73
main.(*Forwarder).ListenAndServe
forwarder.go:28
main.MustRunService
main.go:42
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:2361
дело происходит на ubuntu 16.04
куда копать?
Там же есть про EBADF


Daniel
15.08.2018
11:53:45
я бы хотел понять, почему оно вдруг is not an open file descriptor

Roman
15.08.2018
11:57:52
Не тот fd

Google

Daniel
15.08.2018
12:00:18
не. оно до того справилось 100К+ соединений успешно акцептнуть

Pawel
15.08.2018
12:08:48

Artem
15.08.2018
12:49:50
можно ли абстрактно обратится к полю структуры?
вроде
struct.AnyField == "some" ?

Daniel
15.08.2018
12:50:00
а?!

Artem
15.08.2018
12:51:10
все поля структуры могут принимать только два значения "some" / "not some"
и они должны быть 100% не пустыми
и не хочется писать проверок кучу вроде
if s.FieldOne == "some"

Andrei
15.08.2018
12:51:15

Artem
15.08.2018
12:51:36

Антон
15.08.2018
13:09:01
Добрый день!
помогите мне, пожалуйста, понять поведение каналов в данной ситуации:
Имеется функция, которая вызывается в виде горутины, и туда передается канал, в который нужно передать результат выполнения
чтение из этого канала происходит внутри select'a
по какой-то причине case для этого канала выстреливает дважды
в первый раз в канал передается результат выполнения функции, а во второй уже пустая структура необходимого типа
в чем может быть дело?
сейчас приложу скрины
на первом скриншоте вызов функции create как горутины и чтение из канала, а на втором - реализация этой функции

Aleksandr
15.08.2018
13:11:55
что-то путаешь
у тебя же канал тпиизирован - там не может быть ничего кроме User

Google

Антон
15.08.2018
13:12:36
мне туда приходит пустая структура User

Aleksandr
15.08.2018
13:13:02
значит ее и отправляешь

Andrei
15.08.2018
13:13:30

Антон
15.08.2018
13:13:31
так я же один раз делаю отправку в канал

Crypt
15.08.2018
13:14:12

Антон
15.08.2018
13:15:35

Aleksandr
15.08.2018
13:16:31

Антон
15.08.2018
13:17:01
прошу прощения, забыл его в плейграунде
приходит как параметр в функцию Register
поправил ссылку

Crypt
15.08.2018
13:17:57

Антон
15.08.2018
13:18:32

Aleksandr
15.08.2018
13:19:52
если ты два раза получаешь u, то ты 2 раза его отправляешь

Crypt
15.08.2018
13:19:54
вообще тут каналы не в тему, лучше заюзатьsync.WaitGroup

Aleksandr
15.08.2018
13:20:00
либо ты неверно интерпретируешь то, что видишь
логируй свои действия


Kirill
15.08.2018
13:20:33
коллеги, у меня тут странное, и никогда мной доселе невиданное
у меня есть код:
func (s *Forwarder) listenTCP(addr string) error {
listener, err := net.Listen("tcp4", addr)
if err != nil {
return errors.Wrapf(err, "failed to listen tcp: %s", addr)
}
for {
conn, err := listener.Accept()
if err != nil {
errorsMetric.WithLabelValues("Accept", "tcp").Add(1)
return errors.Wrap(err, "failed to accept connection")
}
acceptedMetric.WithLabelValues("tcp").Add(1)
go checkAndForward(
conn.(*net.TCPConn),
s.Target,
s.Timeout,
s.HeaderLen,
s.ProxyHosts,
)
}
}
и время от времени он выдает мне ошибку в строке conn, err := listener.Accept()
accept tcp4 0.0.0.0:443: bad file descriptor
failed to accept connection
main.(*Forwarder).listenTCP
forwarder.go:73
main.(*Forwarder).ListenAndServe
forwarder.go:28
main.MustRunService
main.go:42
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:2361
дело происходит на ubuntu 16.04
куда копать?
В сторону закрытых со стороны клиента коннекта или на уровне ядра порезанных коннектов?


Антон
15.08.2018
13:21:05

Aleksandr
15.08.2018
13:21:46

Google

Антон
15.08.2018
13:21:51
логируй.
поставил лог в функцию create, выстрелил один раз

Crypt
15.08.2018
13:23:34
вообще странно, что select не блокирует, ведь кроме юзеров ничего не отправляется сейчас, как я понял

Aleksandr
15.08.2018
13:23:40
поставь логи и продемонстрируй выхлоп

Антон
15.08.2018
13:24:01

Aleksandr
15.08.2018
13:24:14

Crypt
15.08.2018
13:24:28
лол ващет
ты юзаешь u для create и для select
попробуй новую переменную объявить

Антон
15.08.2018
13:27:01

Антон
15.08.2018
13:27:20

Aleksandr
15.08.2018
13:28:06
в тот же канал уже не отправить
то есть создается другой
Register два раза вызывается?

Антон
15.08.2018
13:29:06
нет

Aleksandr
15.08.2018
13:33:13
да, я воспроизвел

Google

Aleksandr
15.08.2018
13:33:16
щас разберемся

Антон
15.08.2018
13:33:53
Ура!)
я бы просто переписал на waitGroup, но хочется понять, в чем тут нюанс

Crypt
15.08.2018
13:34:53
https://play.golang.org/p/5B6xzV2r1b7

Антон
15.08.2018
13:35:36
да, тут как раз тоже есть такая беда

Crypt
15.08.2018
13:36:39
https://play.golang.org/p/TcWwQkiWLbr
break зарулил, дело в for
у меня один вопрос - как он читает из закрытого канала и закрывает его еще раз?))))

Антон
15.08.2018
13:38:11

Admin
ERROR: S client not available

Антон
15.08.2018
13:38:19
не, читать то из закрытого канала в принципе вроде ведь можно?
во всяком случае через for range точно можно из него все достать
но откуда в канале берется инфа, после того как он закрывается - загадка

Lesha
15.08.2018
13:39:58
при закрытии канала оно еще что-то пуляет емнип

Антон
15.08.2018
13:40:45

Lesha
15.08.2018
13:40:54
это ожидаемое поведение

Илья
15.08.2018
13:41:48

Crypt
15.08.2018
13:41:48

Илья
15.08.2018
13:41:53
https://dave.cheney.net/2014/03/19/channel-axioms

Антон
15.08.2018
13:42:09
во дела
не знал

Google

Антон
15.08.2018
13:42:21
буду знать)

Aleksandr
15.08.2018
13:42:26
https://play.golang.org/p/FfeL-lVIibl
надо ok проверять

Crypt
15.08.2018
13:42:37

Aleksandr
15.08.2018
13:42:41
иначе читаем из пустого канала

Lesha
15.08.2018
13:43:01

Aleksandr
15.08.2018
13:43:12

Crypt
15.08.2018
13:43:24
даже после вычитывания пустого значения

Andrei
15.08.2018
13:43:45

Илья
15.08.2018
13:43:49

Kirill
15.08.2018
13:45:08
Б-же, у нас что, люди каналы уже не знают?

Lesha
15.08.2018
13:45:32

Илья
15.08.2018
13:45:35

Lesha
15.08.2018
13:46:01

Kirill
15.08.2018
13:46:02

Илья
15.08.2018
13:46:54
https://geeksus.ru/wp-content/uploads/2017/10/13.jpg