#concurrency #erlang #ejabberd
#параллелизм #erlang #ejabberd
Вопрос:
Я создал модуль ведения журнала, который записывает сообщения в базу данных mysql, текущий код находится здесь: https://github.com/amiadogroup/mod_log_chat_mysql5/blob/master/src/mod_log_chat_mysql5.erl
Проблема с текущим кодом заключается в том, что иногда соединение закрывается, и в результате модуль больше не работает. Как вы видите в коде, я сохраняю DBRef в таблице ets, что на самом деле не самый лучший способ.
Я спросил об этом список рассылки erlang, и они предложили мне выполнить подключение к БД в качестве собственного дочернего процесса модуля. Это позволит модулю корректно перезапустить соединение после закрытия соединения.
Теперь мой вопрос: как я могу реализовать этот дочерний процесс с помощью gen_server и / или gen_mod?
Нужно ли мне создавать два файла или я могу сделать это в одном файле?
Есть ли где-нибудь пример того, как я мог бы этого добиться?
Редактировать: как вы можете видеть в связанном репозитории github, я обновил код, и теперь он работает, weeha! Просмотр кода mod_Archive мне очень помог, хотя я не решил обновить свою версию ejabberd.
Теперь я столкнулся с другой, но связанной проблемой. В коде вы видите, что я выполняю начальный запрос с «SET NAMES UTF8», чтобы предотвратить искажение сообщений. Кажется, что это не выполняется снова, если gen_server выполняет повторное подключение. Есть ли какой-либо хук, который я могу вызвать при повторном подключении, чтобы запрос UTF8 выполнялся каждый раз?
Редактировать # 2: теперь я переключился на Emysql (https://github.com/Eonblast/Emysql ) и это работает из коробки, указывая кодировку непосредственно при подключении. Код находится на github.
Спасибо за вашу помощь, Майкл
Ответ №1:
Я предлагаю вам ознакомиться с общими принципами Erlang / OTP (gen_server, supervisor и т. Д.). ejabberd полагается на этот стандартный шаблон архитектуры Erlang.
Что касается вашего комментария к базе данных, ejabberd имеет свой собственный способ управления базой данных и передачи запросов в MySQL, например. Вы также должны изучить это.
Комментарии:
1. Об Erlang / OTP: в настоящее время я делаю это, используя книгу Эрланга о’Рейли. Но я пока не очень уверен, правильно ли я это понял 😉 Что касается собственного подхода к БД: см. Мой комментарий ниже
2. На самом деле, мы не рекомендуем использовать пакет Debian: либо наш двоичный пакет, либо сборку из исходного кода.
Ответ №2:
В вашем исходном коде вы применяете только поведение gen_mod, если вы хотите иметь gen_server, вы можете сделать это в том же модуле, если вы хорошо определяете поведение gen_server.
Хорошим примером может быть модуль ejabberd mod_archive, который реализует оба поведения.
Редактировать: я никогда не работал «напрямую» с mysql на erlang. Но с помощью методов ejabberd я нахожу это довольно «простым» (вам придется выполнить несколько настроек, но довольно просто). У вас есть метод
ejabberd_odbc:sql_query_t(Query)
И имеет пример, который вы можете найти в модуле mod_archive_odbc.
Чтобы использовать этот метод (и последний модуль) Я загрузил собственный драйвер mysql и поместил лучи, созданные из драйвера, в ejabberd ebin dir (вы можете поместить его в любом месте, которое уже давно находится на пути erlang). Программная ссылка на ejabberd ebin — моя любимая:
ln -s <diryouhavethedriver>/ebin/*.beam /usr/lib/ejabberd/ebin/
и выполните несколько настроек для вашего ejabberd.cfg. Этот процесс описан на этой странице в process one. Обратите внимание, что полные шаги должны сделать mysql полной базой данных ejabberd. Возможно, вам это не нужно, поэтому вы должны перейти на несколько шагов.
Надеюсь, это поможет.
Комментарии:
1. Спасибо за ваш ответ. С помощью gen_server я бы запустил подключение к БД? Как я мог тогда получить ссылку на БД?
2. Отредактируйте ответ, чтобы включить немного о mysql, надеюсь, это поможет
3. Спасибо Nuno. Что касается erlang_odbc: проблема здесь в том, что я использую Debian на стороне сервера с ejabberd deb из apt. И, насколько я знаю, deb не компилируется с поддержкой odbc в нем. Знаете ли вы, могу ли я по-прежнему использовать модуль erlang_odbc, если я скомпилирую модуль MySQL самостоятельно? Я никогда не пробовал это, но я не думаю, что это работает: (
4. Он может отличаться от версии к версии, но ejabberd, использующий mysql, был установлен из репозиториев Ubuntu 11.04, а до этого он был у меня на другом компьютере с предыдущей версией ubuntu. Просто не помню, какой именно. Сначала я подумал, что мне нужно будет скомпилировать его из исходного кода, но я попробовал, и все работало нормально.