Fork me on GitHub
#clojure-russia
<
2015-12-02
>
oxgrouby06:12:43

м, значит хоть что-то я могу изменить в этом мире.

lowl4tency06:12:03

oxgrouby: осторожнее, слышал про эффект бабочки?

oxgrouby06:12:55

да, осторожность не помешает )

a.espolov07:12:45

ни кому один чел не нужен в команду для участия clojure cup?

Ivan Fedorov09:12:56

Кто-нибудь может проконсультировать по использованию очередей? У меня в приложение есть задача -- рассылка почты. Формат письма один и тот же, и есть несколько функций которые производят эти письма и сохраняют их в очередь. И у этой очереди есть один отдельный поток-потребитель который забирает из неё письма. Вопрос: как правильно инициализировать этого потребителя? Ну то есть хотелось бы чтобы это был какой-то управляемый поток, подчинённый какому-нибудь пулу и т.д. (я в пулах и executors ноль, почитал бы сурцы).

nicola09:12:31

Ты хочешь в один поток рассылать?

Ivan Fedorov09:12:14

на самом деле, у меня есть ещё несколько таких мест, где надо потребителя как-то управляемо инициализировать.

turtle09:12:20

ognivo: заюзай агенты. Они для этого, можно сказать, и созданы.

Ivan Fedorov09:12:10

turtle: сейчас посмотрю примеры и вернусь

Ivan Fedorov09:12:20

turtle: То есть мне надо обернуть очередь в агента, и с помощью посылаемых функций и параметров туда добавлять элементы. А как управлять вытаскиванием и отсылкой?

Ivan Fedorov09:12:09

Т.е. кто будет посылать агенту функцию send-email-from-queue?

gordon09:12:36

ну агент же сам себе очередь, ты в него засылаешь функцию, он ее выполняет. Если в момент отправки занят, то выполнит ее как доберется

gordon09:12:28

то есть тебе в него нужно не send-email-from-queue отправлять, а send-email

Ivan Fedorov09:12:22

ну в агент надо что-то положить же?

razum2um09:12:58

а вот кстати практический вопрос - как с такой очередью переживать рестарты? получается все равно придется сделать сторадж job с параметрами функции и остальным хламом? чем тогда лучше standalone очереди?

nicola09:12:08

можно просто наверно запустить отдельный поток, лазать во внешнюю очередь и отсылать

gordon09:12:54

это, как говорится, упражнение со звездочкой

razum2um09:12:05

ну да, только почему так выходит то? агенты кул, но на практике надо делать как делают

gordon09:12:27

естественно, если хочется, чтобы ничего не проебалось, то нужно немного по-другому подходить к вопросу)

nicola09:12:34

(.start (Thread. (loop []  (get-jobs) (do-jobs) (recur)))))

nicola09:12:02

Агенты нужны чтобы синкать несколько потоков

Ivan Fedorov09:12:07

@nicola: я сейчас так уже делаю, я хочу управление этим отдельным потоком отдать на аутсорс какому-нибудь экзекутору.

nicola09:12:20

Зачем если он один

Ivan Fedorov09:12:37

Ну он же может умереть.

nicola09:12:38

еще агенты нужны чтобы IO делать для атомов и рефов

razum2um09:12:40

@ognivo: ну вот, получается реальный ответ на вопрос про рассылку это второй ответ Коли, а не первый 😕

nicola09:12:11

поставь try catch simple_smile

Ivan Fedorov09:12:25

Да, я так и живу

nicola09:12:28

если он погибнет, все равно тебе решать что делать

Ivan Fedorov09:12:33

Но хочу идиоматично

razum2um09:12:50

@nicola: а я думал, что нас сейчас будут тролить, что нету let it fail

nicola09:12:51

с агентами в случае exception, нужно пул ресетить - там хитро

razum2um09:12:14

но все же, вот эта шняга, что на практике ответы другие - меня беспокоит

nicola09:12:40

еще раз - агенты для синхронизации

nicola09:12:53

если есть внешняя очередь, то она синкает

nicola09:12:21

если не жалко потерять несколько писем при рестарте, можно через агенты

nicola09:12:36

без внешней очереди

gordon10:12:29

на деле общаться через агентов с внешним миром довольно стремно, внешний мир недружелюбен

nicola10:12:54

второе применение агентов, это io после STM транзакций - Agents are integrated with the STM - any dispatches made in a transaction are held until it commits, and are discarded if it is retried or aborted.

Ivan Fedorov10:12:15

У меня сейчас это всё внутри приложения на ztellman/lamina, и там даже есть какой-то executor, но я пока не добрался до него.

Ivan Fedorov10:12:33

Агенты то понятно как использовать, вопрос по правильному управлению потоком-потребителем скорее.

nicola10:12:01

А что тебя смущает, что ты лишний поток займешь?

Ivan Fedorov10:12:43

Меня смущает что я его сам создаю, да ещё и с коленочным решением вида try catch

gordon10:12:05

они все так внутри устроены

gordon10:12:28

разница лишь в том сам ты этот блок обработки напишешь или кто-то за тебя

nicola10:12:37

так thread pool не решает задачу падения, он занимается распределением потоков

Ivan Fedorov10:12:17

а создание новых потоков?

nicola10:12:30

лучше сказать выделение из пула

nicola10:12:47

как ты вотчишь свою очередь?

nicola10:12:09

полишь?

Ivan Fedorov10:12:17

Просто у меня получается по монолиту размазано это создание потоков, как-то не оч.

Ivan Fedorov10:12:49

Не, не поллю. Просто создаю отдельный поток, и он висит до поступления новых элементов в очередь.

Ivan Fedorov10:12:02

В lamina так можно.

nicola10:12:54

те ты используешь какую-то внутренюю очередь lamina и сам ее не персистешь?

Ivan Fedorov10:12:27

Да. Но кстати, персистить тоже надо бы, это упущение моё.

nicola10:12:23

Я смотрю она на core.async вроде

nicola10:12:06

и те тебе пофиг на потерянные мэйлы simple_smile

nicola10:12:29

Тогда скорее всего нужно посмотреть, что там внутри и в go-loopе рассылать

Ivan Fedorov10:12:01

Она аналог core.async, по-моему даже появилась до него.

nicola10:12:29

Ага, я вижу

Ivan Fedorov10:12:32

Теперь автор её бросил, и написал новую библиотеку manifold

nicola10:12:51

Ну тогда надо встраиваться в ее thread pool

nicola10:12:05

либо тоже ее бросить simple_smile

razum2um10:12:28

@gordon: @nicola вот кстати в связи с этой моей болью, которую вы кажется не понимаете или привыкли, есть идея - есть персистентные структуры - есть концепция event-sourcing которая впринципе может быть встроена в процессы типа swap - почему бы не симулировать persistent memory тем, что мы 1) заставляем писать миграции для данных в памяти 2) на время поднимаем второй экземпляр приложения 3) стримим поток событий на него 4) в момент, когда поток приостановился (т.е. мы балансером перестали пускать на конкретный сервер) - состояние в какой-то момент времени должно совпасть 5) выключаем старый инстанс, запросы идут на новый значимый плюс этого как мне кажется - возможность программировать не усложняя архитектуру, просто полагаясь, что у нас persistent memory возможно я пропустил и это есть или имеет фатальные недостатки?

nicola10:12:47

Ну redis или очереди и есть персистентная память с интроспекцией simple_smile

Ivan Fedorov10:12:50

Я планирую переезжать с lamina на manifold или core.async. Но кор.асинк мне не нравится в плане его нотации со стрелочками и т.д. К этому надо привыкать, видимо.

nicola10:12:39

@ognivo: ну если говорить про идеоматичность, то core.async - идеоматичен simple_smile

razum2um10:12:32

@nicola: да, фактически. но проблема в том, что каждый раз надо думать о настоящей персистентности данных в памяти, почему бы не снять эту сложность совсем для конечного аппа (сделать глобально)?

oxgrouby10:12:17

поцоны, а можно в слаке тему поменять?

oxgrouby10:12:31

всмысле цвета

razum2um10:12:54

@nicola: видел https://github.com/alandipert/enduro? я о том же только глобально

nicola10:12:30

@razum2um: беться человечество над этим simple_smile - http://avout.io/ тудаже

Ivan Fedorov10:12:01

@nicola: а с персистентностью что заюзать? Redis, RabbitMQ? Редис уже стоит и подключён, я там сессии храню.

nicola10:12:13

базы пока привычней и интероперабельней для большинства, пока хватает производительности

nicola10:12:22

redis вполне

razum2um10:12:43

@ognivo: в редисе есть паб-саб это будет лучше полла

Ivan Fedorov10:12:44

спасибо, сэр.

nicola10:12:11

Вон даже какаято либа есть - https://github.com/ptaoussanis/carmine

nicola10:12:26

сам не пробовал - расскажешь если получится simple_smile

razum2um10:12:16

я пробовал, она ок, но вот это и есть accidental complexity архитектуры, а еще кроме avout?

nicola10:12:18

Можно @prepor для ревизии вызвать

Ivan Fedorov10:12:21

@nicola: у меня через неё сессии и работают, дальше не изучал.

Ivan Fedorov10:12:41

@razum2um: спасибо за инфу про паб-саб.

prepor10:12:22

я не понимаю ревизии чего ) зачем мне перзистить оперативную память?

razum2um10:12:49

чтобы проще писать приложения. рассылка? очередь? редис? - просто агент и все

razum2um10:12:08

стейт в базе? датомик? - атом который переживает рестарты

prepor10:12:34

если уж и делать что-то в этом направлении, то совсем на другом уровне.

prepor10:12:02

убирает разделение между оперативной и перзистетной памятью https://en.wikipedia.org/wiki/HP_Labs#The_Machine

prepor10:12:29

> стейт в базе? датомик? - атом который переживает рестарты зачем мне это? оперативная память не просто так появилась, она в тысячу раз быстрее

nicola10:12:34

@prepor Я больше про рассылку на redis simple_smile

razum2um10:12:43

@prepor: так смотри выше. event-sourcing должен спасти. у тебя будет все в оперативе. всегда (пока ты сам этого хочешь и сколько хочешь)

nicola10:12:52

Но про глобальную память тоже интересно

prepor10:12:26

> @prepor: так смотри выше. event-sourcing должен спасти. у тебя будет все в оперативе. всегда ну и что ты будешь делать если твой процесс сдохнет просто? )

nicola10:12:05

Акку или erlang simple_smile

razum2um10:12:10

@prepor: берем начальное состояние (дампится или снапшотится раз в ..) и “догоняем” его

prepor10:12:26

вот у тебя и появился диск

razum2um10:12:37

хех, ну ты сказал, что процесс умер

prepor10:12:48

ну да, а нафига еще перзистить?

razum2um10:12:54

это не каждый день, это чс, а про рестарт смотри выше

nicola10:12:58

а просто диска не достаточно, нужно write ahead log simple_smile

prepor10:12:11

> @prepor Я больше про рассылку на redis simple_smile ну пабсаб вполне работает. только не скейлится (включая редис кластер). ну и carmine так себе либа

nicola10:12:22

и получим postgresql или kafka simple_smile

razum2um10:12:37

дада, kafka как event-source сторадж

nicola10:12:39

а потом еще гарантии консистентности по кластеру

prepor10:12:49

короче, то что ты хочешь это datomic

prepor10:12:57

куда правильнее чем то что ты хочешь

prepor10:12:00

все всегда в памяти

nicola10:12:17

кстати, действительно близко к live indexам датомика

Ivan Fedorov10:12:32

А ещё у меня с "детства" такая идея -- выбросить редис и юзать иннодб через HandlerSocket, но я не знаю с чем я столкнусь в таком случае.

dottedmag10:12:49

Какая интересная штука этот

prepor10:12:29

ну это очень старая либа. ну и не думаю что удачная

nicola10:12:02

иннодб - mysql?

nicola10:12:34

Ну мы для ненагруженных приложений все очереди в postgresql делаем

Ivan Fedorov10:12:04

Да, к иннодб же можно напрямую обращаться через HandlerSocket, и возможно через Memcached Daemon (от Оракла)

prepor10:12:23

эта тема с HandlerSocket вроде как уже несколько лет как протухла. ну оверхеда на sql парсинг и query planning не так много. а когда ты используешь prepared statements так нет и вовсе

prepor10:12:01

при этом плюшки которые дает редис от этого совсем даже не появляются

Ivan Fedorov10:12:52

А какие плюшки у редиса? Вообще, что почитать на тему фундаментальных различий между реляционными БД, редисами, КЗ-хранилищами, персистентными очередями?

razum2um10:12:33

например атомарные операции, протухание записей, блокирующий и неблокирующий интерфесы

prepor10:12:18

нет никакого неблокирующего интерфейса у редиса

prepor10:12:37

у него текстовый протокол, который не умеет асинхронных операций по определению

prepor10:12:36

> А какие плюшки у редиса? ооочень быстрый, транзакционное выполнение lua-скриптиков, вполне неплохой "stdlib" из разных структур данных

prepor10:12:54

expire тоже полезная тема, да

razum2um10:12:59

> The library comes with multiple APIs. There is the synchronous API, the asynchronous API рубишная и кажется скаловская (как минимум, что юзал) либы на нем построены, оно же асинхронное

prepor10:12:07

оно не асинхронное

prepor10:12:23

максимум что ты можешь выжать из редисовского протокола это пайплайнинг

prepor10:12:35

и то почти ни одна либа не умеет делать это автоматически

prepor10:12:23

от того что ты с сокетом на уровне клиента будешь общаться неблокирующе у тебя интерфейс работы с базой асинхронным не станет. т.е. ты не получишь ответ на запрос 2. до тех пор пока не получил 1.

razum2um10:12:33

т.е. я вижу, что там pub-sub

razum2um10:12:55

но все же это написано и видимо багов в нем меньше чем в велосипедах

prepor10:12:04

что "это"?

prepor10:12:16

я говорю что асинхронного интерфейса к редису нет

razum2um10:12:26

ладно, забей, я понял о чем ты

prepor10:12:32

а паб саб у тебя должен использовать отдельный сокет для себя

prepor10:12:47

@kamilogorek: > Вообще, что почитать на тему фундаментальных у Ричи в его списке книжек есть много про БД http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH. Но я сам толком не читал так что советовать не могу )

prepor10:12:20

Foundations of Databases например (но там в основном про даталог таки)

prepor10:12:35

Principles of Database & Knowledge-Base Systems

prepor10:12:51

вот тут про всякое и много про реляционные БД

Ivan Fedorov10:12:52

@prepor: хорошего поста в блоге хватило бы.

razum2um10:12:01

я имел в виду, что написано достаточно, что мне показалось, что оно есть, пусть это и всего лишь ужимка сишного клиента

prepor10:12:02

нууу, это скучно, ок )

razum2um10:12:23

и да, корректно было бы сказать - хорошие неблокирующие либы simple_smile

prepor10:12:03

а их тоже нет, гг

prepor10:12:17

найди ту что умеет работать неблокирующе и с редис кластером? )

razum2um10:12:22

@prepor: лучше скажи, почему avout не торт?

prepor10:12:26

и умеет всякие луа-скриптики

prepor10:12:52

https://github.com/mp911de/lettuce например ломается при фейловере )

prepor10:12:55

> лучше скажи, почему avout не торт? ну ооочень мееедленный распределенный stm тебе может быть нужен только для координирующих действий между серверами. типа выбора лидера, ребалансировки или еще чего-то подобного. и тут вроде как удобнее пользоваться голым ZK-интерфейсом (или библиотеками рецептов сверху него типа curator), чем вот такими конструкциями.

Ivan Fedorov10:12:15

Ок, господа, спасибо, пойду теперь наконец всё пробовать. Наверно, сначала займусь экзекутором из manifold.

prepor11:12:54

manifold же стремный )

Ivan Fedorov11:12:00

я ещё не знаю этого) А что с ним? Я просто использую aleph для http/websockets, он идёт вместе с manifold теперь.

prepor11:12:19

как это вообще все работает?

prepor11:12:20

мне кажется core.async куда правильнее задизайнен.

Ivan Fedorov11:12:21

Пока не знаю, сегодня планировал разведку боем. У меня есть рабочий функционал на lamina, всё работает аналогично кор.асинку, насколько я понимаю.

prepor11:12:47

не аналогично, просто задачи те же решают

prepor11:12:02

поэтому в некоторых местах похоже

Ivan Fedorov11:12:20

да, я так и хотел сказать.

Ivan Fedorov11:12:09

Есть производители которые суют сообщения в канал, и есть некие потребители которые на нём постоянно висят в ожидании новых сообщений.

Ivan Fedorov11:12:02

Полагаю что в манифолде так же.

Ivan Fedorov11:12:01

Сейчас ещё раз посмотрю core.async, но мне пока все эти стрелочки и подмигивания не нравятся)))

Ivan Fedorov11:12:04

Или там есть обычные имена для операций?

prepor11:12:16

да какая разница стрелочки или не стрелочки

prepor11:12:20

суть не в этом

Ivan Fedorov11:12:35

суть то, конечно, не в этом. но сканируемость и понятность кода -- это одна из метрик проекта.

prepor11:12:56

и стрелочки на это вообще ни разу не влияют

nicola11:12:44

дело привычки и соглашений simple_smile

prepor11:12:41

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

prepor11:12:25

если для тебя так важны стрелочки / не стрелочки, то замени их в редакторе на что душе угодно, можно какую-нибудь емоджи подобрать годную

prepor11:12:50

> и как ты ее словишь это к вопросу о манифолде simple_smile

Ivan Fedorov11:12:51

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

turtle11:12:15

ognivo: ну можешь явашный тредпул заюзать... simple_smile

turtle11:12:54

А так send же меняет стейт агента потом. Можно им пренебречь.

turtle11:12:07

Просто (send queue send-mail message)

turtle11:12:25

И усё. Как он доберётся, так выполнит, причём выделением потоков будет сам заниматься.

turtle11:12:45

Но обработку ошибок нужно будет тебе всё равно делать, внутри try .. catch - от него не избавиться.

turtle11:12:40

Стейтом может служить, например, количество отправленных писем. Тоже прикольно. Да и мало ли, любое, что нужно. Главное, чтобы функция его возвращала.

turtle11:12:47

Новый стейт.

lowl4tency11:12:25

a.espolov: а это ты про кложа кап спрашивал?

lowl4tency11:12:44

Там Никита вроде ищет поанов в тиму

ilshad16:12:44

@ognivo: такую задачу ведь персистить надо. Нормальный и надежный способ сделать это на какой-нибудь nosql. монга+монгер - годный, рабочий вариант. Клэймер делает запросы в бесконечном цикле с таймаутом и тд. Такой способ надежнее и гибче любых других извращений.

ilshad16:12:15

а дейтомик я бы не стал для этого юзать, это как из пушки по воробьям

ilshad16:12:28

а монга самое то - это хоть и недобаза, зато минимум возни и пара десятков строк кода на клаймер.

Ivan Fedorov17:12:50

@turtle: так вопрос скорее в том, как грамотно инициализировать поток-потребитель. И у меня таких мест много. Поэтому действительно, или явишный тредпул (спасибо), или ещё какой.

Ivan Fedorov17:12:44

@ilshad: спасибо за предложение, буду иметь в виду, если с паб-сабом у редиса не получится.

robotector17:12:50

> ну и carmine так себе либа @prepor: а почему?

prepor17:12:13

блокирующая, с эксплицитными пайплайнами, с имплицитным стейтом, на сколько я помню по-умолчанию оно все кодирует в свой формат, без возможности легко переключиться на json, скажем), что может оказаться неприятной неожиданностью.

prepor17:12:40

ну и редис кластера там все еще нет работающего, на сколько я понимаю

robotector18:12:32

@prepor: спасибо!