Size: a a a

2020 August 17

ML

Maksim Lapshin in ErlangRus
Alex Bubnov
корень проблемы в том, что в плаге отстутствует малейшее упоминание рантайм-среды и в особенности процессов.
с одной стороны - это типа как благое начинание, с другой - когда это нужно, всё сразу становится очень плохо.
Те сделать собственный протокол на upgrade в плаге мучение?
источник

S

Serg in ErlangRus
Lama Lover
Принимаешь запрос и делаешь GenServer.call в процесс-запрашиватель
В процессе-запрашивателе делаешь запрос в Y и ждёшь ответа
Получив ответ, отвечаешь на call

Конец
да, все классно если б Y отвечал синхронно. Но к меня Y асинхронная система. В ответе я только ref получу и все. Конец не получается.

Потом Y делает callback запрос в мое приложение. Так вот как callback от Y пробросить в процесс-запрашиватель в Elixir грамотно?

В erlang у меня ETS справочник хранит ref запроса и PID. При callback запросе из Y я беру ref и ищу в ETS нужный PID. и вот тогда конец

 А в Elixir как это сделать? опять городить ets + do ...receive и Process.send? Думаю никто так не делает....
источник

LL

Lama Lover in ErlangRus
Serg
да, все классно если б Y отвечал синхронно. Но к меня Y асинхронная система. В ответе я только ref получу и все. Конец не получается.

Потом Y делает callback запрос в мое приложение. Так вот как callback от Y пробросить в процесс-запрашиватель в Elixir грамотно?

В erlang у меня ETS справочник хранит ref запроса и PID. При callback запросе из Y я беру ref и ищу в ETS нужный PID. и вот тогда конец

 А в Elixir как это сделать? опять городить ets + do ...receive и Process.send? Думаю никто так не делает....
Есть прекрасный Registry
Твой процесс запрашиватель совершает запрос и регистрируется в Registry под именем {:requester, request_reference}
Потом когда приходит ответ, плаговский процесс делает запрос на GenServer.cast({:via, Registry, {:requester, request_reference}}, reply_info)
И потом процесс запрашиватель отвечает на call и делает unregister из Registry
источник

LL

Lama Lover in ErlangRus
А самое прикольно то, что потом, если захочется сделать это распределённым, можно лёгким движением руки заменить дефолтный Registry на Horde и всё будет классно работать
источник

LL

Lama Lover in ErlangRus
Lama Lover
Есть прекрасный Registry
Твой процесс запрашиватель совершает запрос и регистрируется в Registry под именем {:requester, request_reference}
Потом когда приходит ответ, плаговский процесс делает запрос на GenServer.cast({:via, Registry, {:requester, request_reference}}, reply_info)
И потом процесс запрашиватель отвечает на call и делает unregister из Registry
Я понятно объяснил?
источник

LL

Lama Lover in ErlangRus
Serg
да, все классно если б Y отвечал синхронно. Но к меня Y асинхронная система. В ответе я только ref получу и все. Конец не получается.

Потом Y делает callback запрос в мое приложение. Так вот как callback от Y пробросить в процесс-запрашиватель в Elixir грамотно?

В erlang у меня ETS справочник хранит ref запроса и PID. При callback запросе из Y я беру ref и ищу в ETS нужный PID. и вот тогда конец

 А в Elixir как это сделать? опять городить ets + do ...receive и Process.send? Думаю никто так не делает....
send + receive заменяется на call в 99% случаев
источник

AB

Alex Bubnov in ErlangRus
Maksim Lapshin
Те сделать собственный протокол на upgrade в плаге мучение?
Не просто мучение, а вообще невозможно by design. Либо патч на plug, либо голый ковбой.
источник

AB

Alex Bubnov in ErlangRus
Нет в плаге апгрейдов
источник

AB

Alex Bubnov in ErlangRus
Alex Bubnov
Нет в плаге апгрейдов
собственно, поэтому как раз в фениксе вместо вебсокетов каналы, и те реализованы невероятно через жопу
источник

S

Serg in ErlangRus
Lama Lover
Я понятно объяснил?
почитаю про Registry. спасибо.
источник

AK

Aleksey Kluchnikov in ErlangRus
Минусы эликсира подьехали?
источник

AK

Aleksey Kluchnikov in ErlangRus
Можно еще noreply/reply gen_server сделать принимающий как запросы так и ответы
источник

AK

Aleksey Kluchnikov in ErlangRus
И хранит словарь рефок в стейте
источник

AB

Alex Bubnov in ErlangRus
Aleksey Kluchnikov
Минусы эликсира подьехали?
так я уже писал, что его главный минус - это рельсовый майндсет в core team
источник

AK

Aleksey Kluchnikov in ErlangRus
Генсервер в эликсире может noreply?
источник

AB

Alex Bubnov in ErlangRus
Aleksey Kluchnikov
Генсервер в эликсире может noreply?
ну конечно может, это ж генсервер
источник

ŹR

Źmićer Rubinštejn in ErlangRus
Aleksey Kluchnikov
Можно еще noreply/reply gen_server сделать принимающий как запросы так и ответы
Тогда получится известнейший боттлнек в генсервере
источник

AK

Aleksey Kluchnikov in ErlangRus
Пул ген серверов )
источник

AK

Aleksey Kluchnikov in ErlangRus
И сами месаги можно не передавать в генсервер, передавать только рефки. И фиг загрузишь тогда этот ботлнек
источник
2020 August 18

I

Ivan in ErlangRus
cleverfox 🦊
давай код. не должно быть такого
Код на Elixir (в чате Эликсира не смогли пока подсказать).

Вот это работает (чтение из файла, вывод в stdout):

Port.open({:spawn, ~s[ffmpeg -i 1.jpg -vf "scale='min(400,iw)':min'(200,ih)':force_original_aspect_ratio=decrease" -loglevel quiet -f image2 pipe:1]}, [:use_stdio, :stream, :exit_status, :binary])
flush()


Это тоже работает (вывод в файл, чтение из stdin, но приходится слать :close, без этого не работает, висит-ждёт):

pid = Port.open({:spawn, ~s[ffmpeg -i pipe:0 -vf "scale='min(400,iw)':min'(200,ih)':force_original_aspect_ratio=decrease" -loglevel quiet -f image2 4.jpg]}, [:use_stdio, :stream, :exit_status, :binary])
{:ok, data} = File.read("1.jpg")
Port.command(pid, data, [])
send(pid, {self(), :close})
flush()


А вот попытка использовать stdin и stdout не работает (шлю :close, как в предыдущем примере, при этом идёт flush по stdin и stdout, но к этому моменту на stdout пусто, и data messages не идут, порт закрывается, ffmpeg пишет в stderr дебаг-инфо о входном и выходном потоках):

pid = Port.open({:spawn, ~s[ffmpeg -i pipe:0 -vf "scale='min(400,iw)':min'(200,ih)':force_original_aspect_ratio=decrease" -loglevel verbose -f image2 pipe:1]}, [:use_stdio, :stream, :exit_status, :binary])
{:ok, data} = File.read("1.jpg")
Port.command(pid, data, [])
send(pid, {self(), :close})
flush()
источник