Ответы пользователя по тегу Erlang
  • Web framework для Erlang

    5HT
    @5HT
    Erlang
    Самый крутой веб фреймворк — это N2O 4.5 MQTT https://mqtt.n2o.space
    Может работать даже без веб сервера!
    Ответ написан
    Комментировать
  • Что производительнее Go или Erlang?

    5HT
    @5HT
    Erlang
    Если задача померяться с пацанами в ЖЖ цифрами и продемонстрировать что ты быстрее эрланга на 5-10% — то Го. Если ты хочешь более-менее фунциональный веб, то Erlang конечно. Но на Го так быстро слепить бенчмарк для веб, который нагнет Erlang не так то просто.
    Ответ написан
    Комментировать
  • Erlang. Почему возникает ошибка при установке релиза с помощью rebar?

    5HT
    @5HT
    Erlang
    В отличии от reltool, новые релиз менеджеры relx и mad сами резолвят все зависимости (сортировка последовательности запуска приложений на основании зависимостей), а mad делает еще и маленькие компактны релизы размером 8МБ. Работает так же как и relx, через sasl/systools. Делать релизы через reltool/rebar — это медленный и deprecated способ.
    Ответ написан
    4 комментария
  • Как запустить cowboy сервер?

    5HT
    @5HT
    Erlang
    Вот пример как запускать cowboy одним файлом под супервизором приложения. Пример взят из документации по N2O — Setup Web Server, это стандартный шаблон application и supervisor в одном флаконе. Здесь использованы два статических эндпойнта, один вебсокет эндпойнт и один HTTP/1 эндпойнт.

    -module(sample).
      -behaviour(supervisor).
      -behaviour(application).
      -export([init/1, start/2, stop/1, main/1]).
    
      start(_,_) -> supervisor:start_link({local,review},review,[]).
      stop(_)    -> ok.
      init([])   -> case cowboy:start_http(http,3,port(),env()) of
                         {ok, _}   -> ok;
                         {error,_} -> halt(abort,[]) end, sup().
    
      sup()    -> { ok, { { one_for_one, 5, 100 }, [] } }.
      port()   -> [ { port, application:get_env(n2o,port,8000)  } ].
      env()    -> [ { env, [ { dispatch, points() } ] } ].
      static() ->   { dir, "apps/sample/priv/static", mime() }.
      n2o()    ->   { dir, "deps/n2o/priv",           mime() }.
      mime()   -> [ { mimetypes, cow_mimetypes, all   } ].
      points() -> cowboy_router:compile([{'_', [
    
                  { "/static/[...]",       n2o_static,  static()},
                  { "/n2o/[...]",          n2o_static,  n2o()},
                  { "/ws/[...]",           n2o_stream,  []},
                  { '_',                   n2o_cowboy,  []} ]}]).
    Ответ написан
    Комментировать
  • Загрузка файлов в Erlang и Cowboy

    5HT
    @5HT
    Erlang
    Вот пример бинарного File Upload без всяких XML, jQuery, Base64, XHR, MIME, miltipart, используя только WebSocket канал. Скорость без буферов 22МБ/s при загрузке CPU 40%, поддерживает докачку при обрывах соединения с обоих сторон: N2O Binary File Transfer Protocol. Описание технологии тут: 5ht.co/ftp.htm Цена вопроса 100 строк кода, код не зависит особо от N2O и может быть перенесен на чистый ковбой.
    Ответ написан
    Комментировать
  • Выбор архитекруты для websockeт'ов. eventloop или акторы?

    5HT
    @5HT
    Erlang
    TL;DR: Имплементация любой системы актеров автоматически является ивент лупом.

    Ивентлупом обычно называются планировщики, например в виде С библиотек таких как libuv, которая используется в node.js, Julia, Rust, а также в ивентлупом называют такие библиотеки как в D, например Vibe.D. Актеры Эрланга это больше чем просто планировщик, это также еще и система обмена сообщениями.

    Если вам не нужно чтобы ваши единицы планирования общались между собой, вам возможно не нужна система актеров, и можно будет быстро это написать прямо на C с использование libuv. Как только вы захотите чтобы единицы планирования общались между собой вам потребуется что-то больше чем просто цикл по стекам.

    Вопрос, к сожалению, не имеет смысла, так как Эрланг предоставляет даже больше чем просто систему актеров. Вы не найдете WebSocket сервер для Erlang который не поддерживает концепцию актеров, а также не найдете WebSocket сервер для Erlang который не поддерживает концепцию event loop.
    Ответ написан
    Комментировать
  • Кто как деплоит Erlang приложения?

    5HT
    @5HT
    Erlang
    Я предпочитаю делать git pull в каталоге на сервере который я патчу в реальном времени.
    После того, как я сделал патч я его комичу прямо из сервера.
    Я пересобираю релизы и докер контейнеры из гита.
    По очереди тушу линию контейнеров кольца и переподнимаю новые.

    Такой worklfow преполагается в mad deploy. Но он будет общаться не по ssh с серверами, а с сервисом в составе архитектуры voxoz, который управляет докер контейнерами slice. Но это пока еще не выложено в публику.
    Ответ написан
    Комментировать
  • Как лучше построить архитектуру серверной части на Erlang (Cowboy) для обмена через WebSocket с мобильными клиентами?

    5HT
    @5HT
    Erlang
    Создание высокопроизводительного WebSocket Erlang релея сопровождается следующим списком задач, которые необходимо будет решить архитектору:

    1. Форматирование сообщений: JSON, BERT, MessagePack
    2. XHR Fallback при отсутствии вебсокетов
    3. Обеспечение подписок между WebSocket процессами через PubSub для чата
    4. Обеспечение клиентского PING и обеспечение рекконектов
    5. Развитая поддержка текстового UTF-8 и бинарного формата

    Веб-сервер cowboy не предоставляет ничего из этого списка. Для 2) есть библиотека bullet но она не всех устроит, ее придется дорабатывать пользователям, если они захотят stateful WebSocket соединение. Это означает, что cowboy является низкоуровневым веб-сервером и для реализации этих жизненно необходимых механизмов вам придется воспользоваться более высокоуровневыми библиотеками, веб-фреймворками, которые берут всю эту рутину прикладного уровня на себя.
    Ответ написан
    Комментировать
  • Как закодировать/раскодировать текст в Erlang?

    5HT
    @5HT
    Erlang
    AES-CBC шифрование с HMAC можно использовать из стандартной библиотеки N2O:

    pickle(Data) ->
        Message = term_to_binary({Data,now()}),
        Padding = size(Message) rem 16,
        Bits = (16-Padding)*8, Key = secret(), IV = crypto:rand_bytes(16),
        Cipher = crypto:block_encrypt(aes_cbc128,Key,IV,<<Message/binary,0:Bits>>),
        Signature = crypto:hmac(sha256,Key,<<Cipher/binary,IV/binary>>),
        base64:encode(<<IV/binary,Signature/binary,Cipher/binary>>).
    
    secret() -> wf:config(n2o,secret,<<"ThisIsClassified">>).
    
    depickle(PickledData) ->
        try Key = secret(),
            Decoded = base64:decode(wf:to_binary(PickledData)),
            <<IV:16/binary,Signature:32/binary,Cipher/binary>> = Decoded,
            Signature = crypto:hmac(sha256,Key,<<Cipher/binary,IV/binary>>),
            {Data,_Time} = binary_to_term(crypto:block_decrypt(aes_cbc128,Key,IV,Cipher),[safe]),
            Data
        catch E:R -> wf:info(?MODULE,"Depicke Error: ~p",[{E,R}]), undefined end.

    https://github.com/5HT/n2o/blob/master/src/handler...

    pickle/1 и depickle/1 прошли верификацию: https://github.com/5HT/n2o/issues/63
    Ответ написан
    Комментировать
  • Какой веб-фреймворк использовать, n2o или Zotonic ?

    5HT
    @5HT
    Erlang
    N2O стоит только потому хотябы что у него есть русскоязычное сообщество и поддержка.

    с ChicagoBoss (полностью выключенные логи) проблемы
    https://github.com/sebastianhoitz/todomanager
    По сути пустая страница на 1КБ. Все сжирает роутинг. Я думаю, что на чикагобосс никто не релизил сайты в продакшен.

    $ wrk -c 50 -r 50 -t 4 -k http://localhost:8001/
    Making 50 requests to http://localhost:8001/
      4 threads and 50 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency   162.69ms  483.80ms   1.69s    89.58%
        Req/Sec     0.00      0.00     0.00    100.00%
      48 requests, 48 sock connections in 1.75s, 47.53KB read
    Requests/sec:     27.42
    Transfer/sec:     27.15KB
    Ответ написан
    Комментировать
  • Как использовать Mnesia в Cowboy приложении?

    5HT
    @5HT
    Erlang
    Erlang Abstract Database synrc.github.io/kvs
    Для хранения цепочек в Key-Value стораджах: Mnesia, Riak, KAI, SQL.
    Ответ написан
    Комментировать
  • Выбор СУБД для веб-сервиса на Erlang?

    5HT
    @5HT
    Erlang
    Ответ написан
    Комментировать
  • Использование Erlang для Web?

    5HT
    @5HT
    Erlang
    Вот примеры Erlang сайтов на Nitrogen совместимом фреймворке N2O:
    skyline.synrc.com
    synrc.com:8080/static/app/index.htm
    Ответ написан
    Комментировать
  • Литература по Erlang

    Комментировать
  • Общий паттерн для работы с записями (erlang)?

    5HT
    @5HT
    Erlang
    Вот parse transform, который превращает proplists в records и обратно.
    https://github.com/5HT/n2o/blob/master/src/n2o_rest.erl
    В контексте задачи применительно к JSON транформациям.
    Вот пример использования:
    https://github.com/synrc/n2o_sample/blob/master/src/users.erl
    Вы просто пишете

    -rest_record(user).

    И для рекорда #user{} автоматически генерируют функции трансформации в proplists и обратно (from_json и to_json).

    Если parse_transform по каким-то причинам не устраивает.
    То вот в образовательных целях минимальный код (map и unmap):

    hunmap([],O,_,_) -> O;
    hunmap([{BK,V}|T],O,Keys,0) -> O;
    hunmap([{BK,V}|T],O,Keys,L) ->
        K = wf:to_atom(BK),
        hunmap(T, setelement(
             wf_utils:indexof(K,Keys),O,wf:to_list(V)), Keys--[K],L-1).
    
    -define(unmap(Record), unmap(P,R) -> 
                         hunmap(P,R,record_info(fields, Record),size(R)-1)).
    -define(map(Record), map(O) ->
        Y = [ try N=lists:nth(1,B), if is_number(N) -> 
                wf:to_binary(B); true -> B end catch _:_ -> B end
              || B <- tl(tuple_to_list(O)) ],
        lists:zip(record_info(fields, Record), Y)).
    Ответ написан
    Комментировать
  • Какие технологии выбрать для написания чата?

    5HT
    @5HT
    Erlang
    Пример чата на Вебсокетах под Erlang:

    event(chat) -> wf:send(chat, wf:q(message)),
    
    body() ->
        wf:async(fun() -> loop() end,chat),
      [ #panel{id=history}, #textbox{id=message}, #button{postback=chat}].
    
    loop() ->
        receive
             Message ->
                 wf:insert_bottom(history, #span{text=Message}),
                 wf:flush()
        end,
        loop().


    Полный пример можно посмотреть здесь:
    https://github.com/5HT/n2o/tree/master/samples
    Ответ написан
    Комментировать