首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在erlang中更改gen_server的回调模块?(gen_server:swap_handler)

如何在erlang中更改gen_server的回调模块?(gen_server:swap_handler)
EN

Stack Overflow用户
提问于 2013-02-07 02:37:08
回答 4查看 379关注 0票数 0

我正在构建一个应用程序,可以在两种模式下运行。沙箱模式和生产模式。

在沙箱模式下,我想在我的gen_server中对数据库进行许多检查:如果表不存在,则创建它;如果列不存在,则添加它;如果列类型不允许我要存储的值,则更改它,等等。

在生产模式下,如果表不存在或列与值的类型不匹配,它将失败,这是可以接受的。

因此,为了避免像"case State#state.is_sandbox of true -> ...“这样的繁琐代码,我希望为我的gen_server使用两个不同的模块,并且我希望在handle_call或handle_info中更改当前的模块。

实际上,我只想从沙箱转到生产环境,但我认为如果它以这种方式工作,它可以反向工作。

谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-02-07 05:12:42

您可以向gen_server中的状态添加module,它是一个模块的名称。然后你将需要两个模块-沙箱和生产,它们都实现了相同的功能(你可以为它创建一个行为)。

gen_server回调将调用module:function,它将是来自沙箱或生产模块的函数。module可以在gen_server的init函数中设置,要更改它,只需在gen_server中添加一个新函数:

代码语言:javascript
运行
复制
use_production() ->
    gen_server:cast(production).

....

handle_cast(production, State) ->
    {noreply, State#state{module = production}).

沙箱模块也是如此。

使用module的gen_server回调示例

代码语言:javascript
运行
复制
handle_call(Msg, _From, #state{module = Module} = State) ->
    Module:function(Msq),
    {reply, ok, State}.

必须在沙箱和生产模块中实现function

票数 3
EN

Stack Overflow用户

发布于 2013-02-07 02:42:18

您可以使用os:getenv/1获取模块名称(当然,在此之前您必须在不同的环境中设置不同的名称)

票数 1
EN

Stack Overflow用户

发布于 2013-02-07 03:11:16

您可以使用具有单个处理程序的gen_event,这允许您返回一个swap_handler元组(请参阅gen_event/handle_*)

而且,您不必在gen_server模型中使用case语句。如果您的州包含沙箱变量,则可以通过绑定标头中的沙箱值为回调函数定义不同的子句。例如:

代码语言:javascript
运行
复制
handle_call(do_stuff, _From, State = #state{sandbox = true}) ->
    do_sandbox_stuff();
handle_call(do_stuff, _From, State) ->
    do_nonsandbox_stuff().

在function子句中绑定变量这种方式也是提高效率的良好实践(因为变量绑定在函数体之外,绑定过程在调度器中完成,因此不计入函数的执行时间,而所有匹配都在case中的函数体内部完成)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14736323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档