是否可以确保在初始化后以超时0立即执行handle_info? [英] Is handle_info guaranteed to be executed immediately after init with timeout 0?

查看:126
本文介绍了是否可以确保在初始化后以超时0立即执行handle_info?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到一个奇怪的错误报告,使我认为在gen_server初始化之前已经执行了一些调用。

I am getting a strange error report that makes me think some calls are being executed before the gen_server initialization.

这是初始化代码:

init([ResourceId]) ->
    process_flag(trap_exit, true),
    {ok, {not_initialized, ResourceId}, 0}.

此处是应该初始化资源的handle_info。

Here is the handle_info that should initialize the resource.

handle_info(timeout, {not_initialized, ResourceId}) ->
    Resource = data_store:get_resource(ResourceId),
    {noreply, Resource, ?CACHE_TIMEOUT};

data_store:get_resource(ResourceId)的返回值是#resouce {}记录,用于匹配所有的handle_call方法。

the return value of data_store:get_resource(ResourceId) is the #resouce{} record, used to match all the handle_call methods.

由于该过程仍未初始化,因此带有函数子句的崩溃报告。

The crash report with a function clause since the process is still not initialized.

=CRASH REPORT==== 1-Feb-2013::14:20:03 ===
crasher:
  initial call: gbanga_resources:init/1
  pid: <0.11772.0>  
  registered_name: []
  exception exit: {function_clause,
                      [{gbanga_resources,terminate,
                           [{function_clause,
                                [{gbanga_resources,handle_call,
                                     [get_resource,
                                      {<0.11658.0>,#Ref<0.0.0.240914>},
                                      {not_initialized,12697711}],
                                     [{file,"src/gbanga_resources.erl"},
                                      {line,120}]},
                                 {gen_server,handle_msg,5,
                                     [{file,"gen_server.erl"},{line,588}]},
                                 {proc_lib,init_p_do_apply,3,
                                     [{file,"proc_lib.erl"},{line,227}]}]},
                            {not_initialized,12697711}],
                           [{file,"src/gbanga_resources.erl"},{line,176}]},
                       {gen_server,terminate,6,
                           [{file,"gen_server.erl"},{line,722}]},
                       {proc_lib,init_p_do_apply,3,
                           [{file,"proc_lib.erl"},{line,227}]}]}
    in function  gen_server:terminate/6 (gen_server.erl, line 725)
  ancestors: [gbanga_resources_sup,gbanga_workers_sup,<0.92.0>]
  messages: [{'$gen_call',{<0.11638.0>,#Ref<0.0.0.240915>},get_resource},
                {'$gen_call',{<0.11633.0>,#Ref<0.0.0.240916>},get_resource}]
  links: [<0.6609.0>]
  dictionary: []

如果在所有handle_call之前始终调用handle_info超时,则永远不会发生

This should never happens if the handle_info timeout allways is called before any handle_call.

有人知道为什么会这样吗?

Does anyone knows why this is happening ?

推荐答案

保证?否。超时是任何其他消息。如果在init函数的中间过程中收到其他进程的消息,则可能会先处理该消息。

Guaranteed? No. The timeout is a message like any other. If during the middle of the init function you receive a message from another process, you will likely process that message first.

话虽如此,init函数 对于OTP进程 ,例如gen_server与调用进程是同步的,这意味着该进程将在您收到Pid时完成其初始化功能,这使得另一个进程极其难以发送请求。

That being said, the init function for OTP processes like gen_server is synchronous from the calling process, meaning that the process will have finished its init function by the time you receive the Pid, making it exceedingly difficult for another process to send a message to it before it has a chance to execute the timeout.

当然,我不建议为此行为使用超时。它的定义不太明确,因为该过程从init返回时或多或少会产生收益,并且不能保证Erlang中的计时器准确按时触发(timer:sleep(5000)将在睡眠至少五秒钟,而不是五秒钟。而是向 self()发送一条消息。这会使进程立即知道它有工作要做,因为消息会在初始化返回前 出现在您的邮箱中。

Of course, I would not recommend using a timeout for this behavior. It's less well-defined what will happen, because the process is more-or-less yielding when it returns from init, and timers in Erlang are not guaranteed to fire exactly on time (timer:sleep(5000) will sleep at least five seconds, not exactly five seconds). Instead, send a message to self(); this lets the process know immediately that it has work to do, as the message winds up in your mailbox before init returns.

这篇关于是否可以确保在初始化后以超时0立即执行handle_info?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆