Andrey
лишнее усложнение. Зачем мне держать постоянно запущенный воркер?
Andrey
это усложнит его код
Andrey
там всего лишь прокси из канала в gRPC
Zver
лишнее усложнение. Зачем мне держать постоянно запущенный воркер?
Чтобы работал. И чем это усложняет код? А канал каналов с кучей воркеров это не усложнение?
Andrey
кстати да, этот воркер является gRPC сервисом, он запускается внешним вызовом. Вы мне предлагаете самостоятельно запскать постоянный пул воркеров, это тупо лишняя прослойка
Daniel
мы вам предлагаем подумать еще раз над каналом каналов. вот это уж точно лишняя прослойка
Andrey
а канал указателей вас не смутит?
Andrey
в чём проблема канала каналов?
Andrey
ну вот я не знаю, чем канал каналов хуже канала указателей
Andrey
каналы передавать, ёпт
Andrey
ладно, гуру, пошёл я
Толя
Andrey
я ещё слайсы слайсов использую. И указатели на указатели.
Daniel
ну вот я не знаю, чем канал каналов хуже канала указателей
если вы по каналу указатель паснули, и себе оставили, чтобы потом немного поменять данные - ни чем не хуже, такая же мерзость
Andrey
никто не отменял необходимость мутексов и прочей синхронизации
Daniel
коллега, нравится вам ваша идея - делайте. мы вам сказали, что у вас с архитектурой беда, но и все, заставить не можем и не хотим.
Vladimir
в чём проблема канала каналов?
Опиши точнее задачу что ли, мы тебе скажем чем это заменить.
Vladimir
В целом канал каналов это ебанный пиздец и говно в архитектуре обычно
Andrey
коллега, нравится вам ваша идея - делайте. мы вам сказали, что у вас с архитектурой беда, но и все, заставить не можем и не хотим.
и я услышал только "архитектура беда", к сожалению. Тем не менее, ценю вашу готовность помочь. Постараюсь перефразировать вопрос.
Andrey
если кратко, то нужно придумать func Broadcast(ev Event), которая рассылает некие данные подписчикам. Другими словами, реализовать pubsub на Go. Подписчики - горутины, которые порождаются по внешнему вызову, и транслируют евенты дальше. Пока задумка такая: поднять горутину, которая будет принимать евенты и рассылать их по каналам подписчикам.
Alexander
В целом канал каналов это ебанный пиздец и говно в архитектуре обычно
Типичное применение - запустить какой-то асинхронный процесс и получить от него ответ. При этом если есть пул воркеров и они получают задания через канал, то это будет канал структур. А одно из полей в структуре - канал, в который писать ответ. В чем принципиальная разница с каналом каналов?
Alexander
если кратко, то нужно придумать func Broadcast(ev Event), которая рассылает некие данные подписчикам. Другими словами, реализовать pubsub на Go. Подписчики - горутины, которые порождаются по внешнему вызову, и транслируют евенты дальше. Пока задумка такая: поднять горутину, которая будет принимать евенты и рассылать их по каналам подписчикам.
Тут есть потенциальная проблема с тем, как закрывать каналы. Закрывать должен тот, кто пишет. А как этот Broadcast узнает, что канал можно закрывать? Делать еще один сигнальный канал? Так совсем недолго в них окончательно запутаться
Daniel
коллеги
Alexander
канал каналов канает и будет канать
Andrey
Если приёмник хочет закрыться, он по каналу каналов отдаёт свой канал броадкастеру и тот его закрывает и убирает из списка
Andrey
дальше приёмник видит признак закрытия и спокойно завершается
Andrey
не, можно конечно структуру вокруг приёмника навертеть, и передавать её. Но зачем, если там один канал?
Daniel
скажите мне, вот эти рассуждения, про "закрывать должен тот, кто пишет, но инициировать этот процесс должен тот, кто читает" - они не вызывают у вас ощущения ментального нездоровья? например, ваш писатель заблокирован на записи в канал (запросто, если читателей нет). как вы ему посигналите-то? или оно у вас там в селекте в цикле пишет, и еще ведет учет читателей, и, если их не осталось, прекращает? тогда при чем тут канал каналов? я, короче, обеспокоен. может, вам принять чего успокоительного?
Andrey
Если мне нужен новый приёмник, то я прошу для него канал у броадкастера, он его инициализирует и добавляет в список
Daniel
просите, при чем тут канал каналов?
Daniel
тогда он и решать должен, когда закрывать, правда?
Andrey
просите, при чем тут канал каналов?
при запросе нового канала, канал каналов не участвует.
Andrey
тогда он и решать должен, когда закрывать, правда?
ну нет же. Вы подписались на газету, вы и решаете, когда подписку окончить. Но рассылку закрывает издатель по вашему решению
Andrey
Vladislav
а утечек не будет?
GC все сделает.
Andrey
А почему нельзя всем просто подписаться на один канал?
потому что броадкаст. Сообщение должно дойти всем, а не одному из воркеров
Andrey
pubsub, если вам это чтото говорит
Andrey
давайте без метафор. канал сам по себе метафора...
без метафор, подписку отменяет подписчик
Daniel
и как он сообщает об отмене рассыльщику?
Andrey
вызывает RemoveLogger(lC chan Event) - это метод структуры, в кторой есть loggerStopC chan<- chan Event куда пересылается lC, чтоб его закрыть
Daniel
ничего не понял :(
Andrey
ща
Andrey
тогда он заблочится на посылке.
Daniel
так он уже!
Andrey
а я этого не хочу
Roman
тогда он заблочится на посылке.
Тогда вся система заблочится. А это плохо.
Vladislav
А если издатель еще не получил ваше сообщение, а подписчик уже не хочет получать, но он уже пытается отосласть?
Andrey
так он уже!
нет, там в селекте помимо ветки записи в канал есть <-loggerStopC
Andrey
ща погодите, я код покажу
Andrey
https://play.golang.org/p/Zn3puXO3dqv
Andrey
это броадкастер. на eventC он принимает сообщения, которые надо броадкастить. На loggerCC - каналы новых подписчиков. На loggerStopC - каналы старых подписчиков, которые надо закрыть.
Daniel
о, явой потянуло....
Andrey
на стороне подписчика мы выходим только при закрытии канала, чтобы избежать блокировки броадкастера
Andrey
броадкастер при выходе закрывает все каналы подписчиков. Это надо в defer наверное обернуть
Andrey
о, явой потянуло....
нунизнаю, с явой не дружу
Daniel
зачем нужен тип EventProcessor?
Vladislav
https://play.golang.org/p/Zn3puXO3dqv
строчки 59-62: приходит event, начинается итерация, один из последних подписчиков решил, что больше не хочет слушать, итерация доходит до него и все застывает.
Andrey
зачем нужен тип EventProcessor?
чтоб где-то в майне сделать ep := *EventProvessor{} err := ep.Start()
Daniel
о!
Andrey
строчки 59-62: приходит event, начинается итерация, один из последних подписчиков решил, что больше не хочет слушать, итерация доходит до него и все застывает.
если он решил, что не слушает, то он зовёт ep.RemoveLogger() и продолжает слушать. А выходит только при закрытии.
Andrey
вся эта чехарда с каналом каналов, для того чтобы не окружать мутексами loggerCs = make(map[chan<- Event]bool) // set of channels
Andrey
и при этом добавление нового подписчика не блокируется, послал в буферизованный канал, и дальше работаешь
Vladislav
Ну каналами каналов то лучше обложиться.
Andrey
можно обойтись без. Тогда надо loggerCs перенести в структуру, блокироваться мутексом при добавлении нового логгера, блокироваться мутексом при удалении логгера, а самое важное, блокироваться мутексом перед рассылкой броадкаста, чтоб список каналов для рассылки никто не трогал
Daniel
у вас в канале два мутекса, если вы про производительность
Andrey
не совсем про производительность. Добавление/удаление логгера может гипотетически заблокировать рассылку.
Andrey
ведь мне нельзя делать range по списку каналов, если он модифицируется