Ejabberd模块与子进程

时间:2011-10-12 09:12:52

标签: concurrency erlang ejabberd

我创建了一个记录模块,它将消息记录到mysql db,当前代码位于: https://github.com/amiadogroup/mod_log_chat_mysql5/blob/master/src/mod_log_chat_mysql5.erl

当前代码的问题是,有时连接被关闭,因此模块不再工作。 正如您在代码中看到的,我将DBRef存储在ets表中,这不是真正的好方法。

我向erlang邮件列表询问了这个问题,他们建议我将DB Connection作为模块的子进程。这将使模块在关闭连接时正常重新启动连接。

现在我的问题是:如何使用gen_server和/或gen_mod实现这个子进程?

我是否需要创建两个文件,或者我可以在同一个文件中创建吗?

关于如何实现这个目标,有什么例子吗?

编辑:正如您在链接的github repo中看到的那样,我更新了代码并且现在可以使用了,weeha! 看看mod_Archive代码帮了我很多,虽然我没有决定升级我的ejabberd版本。

我遇到了另一个但相关的问题。在代码中,您看到我使用“SET NAMES UTF8”进行初始查询以防止消息混乱。如果gen_server重新连接,似乎不会再次执行此操作。我可以在重新连接时调用任何钩子,以便每次都进行UTF8查询吗?

修改#2: 现在我切换到Emysql(https://github.com/Eonblast/Emysql),它通过直接在connect上指定编码而开箱即用。 代码在github上。

感谢您的帮助, 迈克尔

2 个答案:

答案 0 :(得分:2)

我建议你研究一般的Erlang / OTP原则(gen_server,supervisor等)。 ejabberd依赖于这种标准的Erlang架构模式。

关于您对数据库的评论,ejabberd有自己的方法来管理数据库并将查询传递给MySQL。你也应该深入研究它。

答案 1 :(得分:1)

在您的源代码中,您只应用gen_mod行为,如果您希望拥有gen_server,则可以在同一模块中执行,如果您定义gen_server行为已经很好。

一个很好的例子是ejabberd模块mod_archive,它实现了这两种行为。


编辑:我从未在erlang上直接使用mysql工作过。但通过ejabberd方法,我发现它非常“简单”(你必须做一些设置,但相当容易)。你有方法

ejabberd_odbc:sql_query_t(Query)

有一个例子,你可以在模块mod_archive_odbc上找到它。

要使用该方法(和最后一个模块)我已经下载了mysql本机驱动程序并将驱动程序创建的梁放在ejabberd ebin目录中(你可以把它放在任何地方,长期在erlang路径上)。 我最喜欢的是ejabberd ebin的软链接:

ln -s <diryouhavethedriver>/ebin/*.beam /usr/lib/ejabberd/ebin/

并在你的ejabberd.cfg上做一些配置。此过程在this page on process one中描述。请注意,完整的步骤是使mysql成为ejabberd的完整数据库。你可能不希望这样,所以你必须跳几步。 希望这有帮助。