Erlang模塊gen_fsm翻譯

模塊摘要
    通用有限狀態機行爲。
 
描述
    用於實現有限狀態機的行爲模塊。使用該模塊實現的通用有限狀態機進程(gen_fsm)將具備一組標準的接口函數,幷包括用於跟蹤和錯誤報告的功能。它也適用於OTP監督樹。有關更多信息,請參閱OTP設計原則。
    gen_fsm假定全部特定部分都位於回調模塊中,導出預約義的函數集。行爲函數和回調函數之間的關係能夠說明以下:
gen_fsm module Callback module
-------------- ---------------
gen_fsm:start_link -----> Module:init/1
 
gen_fsm:send_event -----> Module:StateName/2
 
gen_fsm:send_all_state_event -----> Module:handle_event/3
 
gen_fsm:sync_send_event -----> Module:StateName/3
 
gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
 
- -----> Module:handle_info/3
 
- -----> Module:terminate/3
 
- -----> Module:code_change/4
    若是回調函數失敗或返回錯誤值,gen_fsm將終止。
    gen_fsm處理系統消息,如sys(3)中所述。該SYS模塊可用於調試gen_fsm。
    請注意,gen_fsm不會自動捕獲退出信號,必須在回調模塊中明確啓動。
    除非另有說明,不然若是指定的gen_fsm不存在或者給出了錯誤的參數,則此模塊中的全部函數都將失敗。
    若是回調函數指定'hibernate'而不是超時值,gen_fsm進程能夠進入休眠狀態(參見erlang(3))。若是預計服務器長時間處於空閒狀態,這可能頗有用。可是,應謹慎使用此功能,由於休眠意味着至少有兩個垃圾收集(在休眠時和喚醒後不久),對於忙的狀態機器並不想在每一次調用之間處理垃圾回收。
 
導出
start_link(Module, Args, Options) -> Result
start_link(FsmName, Module, Args, Options) -> Result
    Types:
        FsmName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
         Name = atom()
         GlobalName = ViaName = term()
        Module = atom()
        Args = term()
        Options = [Option]
         Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
         Dbgs = [Dbg]
         Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
         SOpts = [SOpt]
         SOpt - 見erlang:spawn_opt/2,3,4,5
        Result = {ok,Pid} | ignore | {error,Error}
         Pid = pid()
         Error = {already_started,Pid} | term()
    建立gen_fsm進程做爲監督樹的一部分。該功能應由監督樹直接或間接調用。除其餘外,它將確保gen_fsm連接到監督樹。
    gen_fsm進程調用Module:init/1進行初始化。爲確保同步啓動過程,在Module:init/1返回以前,start_link/3,4不會返回。
    若是FsmName = {local,Name},則gen_fsm使用register/2在本地註冊爲Name。若是FsmName = {global,GlobalName},則gen_fsm使用global:register_name/2全局註冊爲GlobalName。若是EventMgrName={via,Module,ViaName},則事件管理器註冊用Module表示的註冊表。所述模塊的回調應該導出的函數register_name/2,unregister_name/1,whereis_name/1和send/2,其行爲應與global中的相應函數相同。所以,{via,global,GlobalName}是有效的引用。
    若是未提供名稱,則不會註冊gen_fsm。
    Module是回調模塊的名稱。
    Args是一個任意項,它做爲參數傳遞給Module:init/1。
    若是選項{timeout,Time}存在,則容許gen_fsm花費Time毫秒初始化,或者它將被終止,啓動函數將返回 {error,timeout}。
    若是存在選項{debug,Dbgs},則將爲Dbgs中的每一個項調用相應的sys函數。見sys(3)。
    若是選項{spawn_opt,SOpts}存在,則SOpts將做爲選項列表傳遞給spawn_opt BIF,後者用於生成gen_fsm進程。見erlang(3)。
    注意
        目前不容許使用spawn選項monitor,但會致使函數失敗,緣由爲badarg。
    若是gen_fsm成功建立並初始化,則函數返回{ok,Pid},其中Pid是gen_fsm的pid。若是已存在具備指定FsmName的進程,則該函數返回 {error,{already_started,Pid}},其中Pid是該進程的pid。
    若是Module:init/1因Reason而失敗,則函數返回{error,Reason}。若是Module:init/1返回{stop,Reason}或ignore,則進程終止,函數分別返回{error,Reason}或ignore。
 
start(Module, Args, Options) -> Result
start(FsmName, Module, Args, Options) -> Result
    Types:
        FsmName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
         Name = atom()
         GlobalName = ViaName = term()
        Module = atom()
        Args = term()
        Options = [Option]
         Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
         Dbgs = [Dbg]
         Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
         SOpts = [term()]
        Result = {ok,Pid} | ignore | {error,Error}
         Pid = pid()
         Error = {already_started,Pid} | term()
    建立一個獨立的gen_fsm進程,即gen_fsm,它不是監督樹的一部分,所以沒有監督者。
    有關參數和返回值的說明,請參見start_link/3,4。
 
send_event(FsmRef, Event) -> ok
    Types:
        FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
         Name = Node = atom()
         GlobalName = ViaName = term()
        Event = term()
    將事件異步發送到gen_fsm FsmRef並當即返回ok。gen_fsm將調用Module:StateName/2來處理事件,其中StateName是gen_fsm的當前狀態的名稱。
    FsmRef能夠是:
    pid,
    Name,若是gen_fsm在本地註冊,
    {Name,Node},若是gen_fsm在另外一個節點本地註冊,或者
    {global,GlobalName},若是gen_fsm是全局註冊的,
    {via,Module,ViaName},若是事件管理器是經過可選進程註冊表註冊的,
    Event是一個任意項,做爲Module:StateName/2的參數之一傳遞。
 
send_all_state_event(FsmRef, Event) -> ok
    Types:
        FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
         Name = Node = atom()
         GlobalName = ViaName = term()
        Event = term()
    將事件異步發送到gen_fsm FsmRef並當即返回ok。gen_fsm將調用Module:handle_event/3來處理事件。
    有關參數的說明,請參閱send_event/2。
    send_event和send_all_state_event之間的區別在於使用哪一個回調函數來處理事件。在每一個狀態下發送事件以相同方式被處理,此函數頗有用,由於在每一個狀態名稱函數中只須要一個handle_event子句來處理事件而不是每一個狀態名函數一個子句。
 
sync_send_event(FsmRef, Event) -> Reply
sync_send_event(FsmRef, Event, Timeout) -> Reply
    Types:
        FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
         Name = Node = atom()
         GlobalName = ViaName = term()
        Event = term()
        Timeout = int()>0 | infinity
        Reply = term()
    將事件發送到gen_fsm FsmRef並等待,直到回覆到達或發生超時。gen_fsm將調用Module:StateName/3來處理事件,其中 StateName是gen_fsm的當前狀態的名稱。
    有關FsmRef和Event 的說明,請參閱send_event/2。
    Timeout是一個大於零的整數,它指定等待回覆的毫秒數,或無限期等待的原子infinity。默認值爲5000.若是在指定時間內未收到回覆,則函數調用失敗。
    返回值Reply在Module:StateName/3的返回值中定義。
    在OTP R12B/Erlang 5.6中刪除了在鏈接到客戶端時,若是服務器在調用期間掛了,有時會消耗服務器退出消息的古老行爲。
 
sync_send_all_state_event(FsmRef, Event) -> Reply
sync_send_all_state_event(FsmRef, Event, Timeout) -> Reply
    Types:
        FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
         Name = Node = atom()
         GlobalName = ViaName = term()
        Event = term()
        Timeout = int()>0 | infinity
        Reply = term()
    將事件發送到gen_fsm FsmRef並等待,直到回覆到達或發生超時。gen_fsm將調用Module:handle_sync_event/4來處理事件。
    有關FsmRef和Event的說明,請參閱send_event/2。有關Timeout和Reply的說明,請參閱sync_send_event/3。
    見send_all_state_event/2,討論sync_send_event和sync_send_all_state_event的區別。
 
reply(Caller, Reply) -> true
    Types:
        Caller - 見下面
        Reply = term()
    當沒法在Module:State/3或Module:handle_sync_event/4的返回值中定義回覆時,gen_fsm可使用此函數向客戶端進程顯式發送回覆,當調用sync_send_event/2,3或sync_send_all_state_event/2,3。 
    Caller必須是提供給回調函數的From參數。Reply是一個任意項,它將做爲sync_send_event/2,3或sync_send_all_state_event/2,3的返回值返回給客戶端。
 
send_event_after(Time, Event) -> Ref
    Types:
        Time = integer()
        Event = term()
        Ref = reference()
    在gen_fsm內部發送延遲事件,在time ms後調用此函數。使用cancel_timer/1可用於取消延遲發送的引用,當即返回。
    gen_fsm將調用Module:StateName/2來處理事件,其中StateName是傳遞延遲事件時gen_fsm的當前狀態的名稱。
    Event是一個任意項,做爲Module:StateName/2的參數之一傳遞。
 
start_timer(Time, Msg) -> Ref
    Types:
        Time = integer()
        Msg = term()
        Ref = reference()
    在gen_fsm內部發送超時事件,在Time ms後調用此函數。當即返回可用於使用cancel_timer/1取消計時器的引用。
    gen_fsm將調用Module:StateName/2來處理事件,其中StateName是傳遞超時消息時gen_fsm的當前狀態的名稱。
    Msg是一個任意的術語,它在超時消息{timeout,Ref,Msg}中傳遞,做爲Module:StateName/2的參數之一。
 
cancel_timer(Ref) -> RemainingTime | false
    Types:
        Ref = reference()
        RemainingTime = integer()
    取消gen_fsm中Ref引用的內部計時器。
    Ref是從send_event_after/2 或 start_timer/2返回的引用。
    若是計時器已經超時,但事件還沒有發送,則會被取消,就好像它沒有超時同樣,所以今後函數返回後將沒有錯誤的計時器事件。
    若是Ref引用活動計時器,則返回以毫秒爲單位的剩餘時間,直到計時器到期爲止,不然返回false。
 
enter_loop(Module, Options, StateName, StateData)
enter_loop(Module, Options, StateName, StateData, FsmName)
enter_loop(Module, Options, StateName, StateData, Timeout)
enter_loop(Module, Options, StateName, StateData, FsmName, Timeout)
    Types:
        Module = atom()
        Options = [Option]
         Option = {debug,Dbgs}
          Dbgs = [Dbg]
           Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
        StateName = atom()
        StateData = term()
        FsmName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
         Name = atom()
         GlobalName = ViaName = term()
        Timeout = int() | infinity
    將現有進程轉換爲gen_fsm。不返回,而是調用進程將進入gen_fsm接收receive循環併成爲gen_fsm進程。該進程必須使用proc_lib中的啓動函數被啓動,參看proc_lib(3)。用戶對進程初始化負責,包括註冊名字。
    當須要比gen_fsm行爲提供的更復雜的初始化過程時,此函數頗有用。
    Module,Options和FsmName與調用start[_link]/3,4時的含義相同。可是,若是指定了FsmName,則必須在調用此函數以前相應地註冊該進程。
    StateName,StateData和Timeout與Module:init/1的返回值具備相同的含義 。此外,回調模塊Module不須要導出init/1功能。
    失敗:若是調用進程未由proc_lib啓動函數啓動,或者未根據FsmName註冊。
 
回調函數
    應從gen_fsm回調模塊導出如下函數。
    在描述中,表達式state name用於表示狀態機的狀態。state data用於表示實現狀態機的Erlang進程的內部狀態。
 
導出
Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate} | {error,Reason}
    Types:
        InitArgs = Args | {Args,Term}
        Args = Term = term()
        State = term()
        Reason = term()
    每當將新事件處理程序添加到事件管理器時,都會調用此函數來初始化事件處理程序。
    若是添加了事件處理程序,因爲調用gen_event:add_handler/3或gen_event:add_sup_handler/3,則InitArgs是這些函數的Args參數。
    若是事件處理程序因爲調用gen_event:swap_handler/3或gen_event:swap_sup_handler/3而替換另外一個事件處理程序,或者因爲來自其餘一個回調函數的交換返回元組,則InitArgs是一個元組{Args,Term} 其中Args是函數call/return元組中提供的參數,Term是終止舊事件處理程序的結果,請參閱gen_event:swap_handler/3。
    若是成功,該函數應返回{ok,State}或{ok,State,hibernate},其中State是事件處理程序的初始內部狀態。
    若是返回{ok,State,hibernate},則事件管理器將進入休眠狀態(經過調用proc_lib:hibernate/3),等待下一個事件發生。 
 
Module:StateName(Event, StateData) -> Result
    Types:
        Event = timeout | term()
        StateData = term()
        Result = {next_state,NextStateName,NewStateData} 
    | {next_state,NextStateName,NewStateData,Timeout}
    | {next_state,NextStateName,NewStateData,hibernate}
    | {stop,Reason,NewStateData}
         NextStateName = atom()
         NewStateData = term()
         Timeout = int()>0 | infinity
         Reason = term()
    每一個可能的狀態名稱應該有一個此函數的實例。每當gen_fsm接收到使用gen_fsm:send_event/2發送的事件時,將調用與當前狀態名稱StateName同名的此函數的實例來處理該事件。 若是發生超時,也會調用它。
    事件是原子timeout,若是發生超時,Event提供參數給send_event/2。
    StateData是gen_fsm的狀態數據。
    若是函數返回{next_state,NextStateName,NewStateData},{next_state,NextStateName,NewStateData,Timeout}或{next_state,NextStateName,NewStateData,hibernate},gen_fsm將繼續執行,當前狀態名稱設置爲NextStateName而且可能更新狀態數據NewStateData。 有關Timeout和hibernate的說明,請參閱Module:init/1。
    若是函數返回{stop,Reason,NewStateData},gen_fsm將調用Module:terminate(Reason,NewStateData)並終止。      
 
Module:handle_event(Event, StateName, StateData) -> Result
    Types:
        Event = term()
        StateName = atom()
        StateData = term()
        Result = {next_state,NextStateName,NewStateData} 
        | {next_state,NextStateName,NewStateData,Timeout}
        | {next_state,NextStateName,NewStateData,hibernate}
        | {stop,Reason,NewStateData}
        NextStateName = atom()
        NewStateData = term()
        Timeout = int()>0 | infinity
        Reason = term()   
    每當gen_fsm接收到使用gen_fsm:send_all_state_event/2發送的事件時,就會調用此函數來處理該事件。
    StateName是gen_fsm的當前狀態名稱。
    有關其餘參數和可能的返回值的說明,請參閱Module:StateName/2。 
 
Module:StateName(Event, From, StateData) -> Result
    Types:
        Event = term()
        From = {pid(),Tag}
        StateData = term()
        Result = {reply,Reply,NextStateName,NewStateData}
        | {reply,Reply,NextStateName,NewStateData,Timeout}
        | {reply,Reply,NextStateName,NewStateData,hibernate}
        | {next_state,NextStateName,NewStateData}
        | {next_state,NextStateName,NewStateData,Timeout}
        | {next_state,NextStateName,NewStateData,hibernate}
        | {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData}
        Reply = term()
        NextStateName = atom()
        NewStateData = term()
        Timeout = int()>0 | infinity
        Reason = normal | term()   
    每一個可能的狀態名稱應該有一個此函數的實例。每當gen_fsm接收到使用gen_fsm:sync_send_event/2,3發送的事件時,將調用與當前狀態名稱StateName同名的此函數的實例來處理該事件。
    Event是提供給sync_send_event的Event參數。
    From是一個元組{Pid,Tag},其中Pid是名爲sync_send_event/2,3進程的pid,Tag是惟一標記。
    StateData是gen_fsm的狀態數據。
    若是函數返回{reply,Reply,NextStateName,NewStateData},{reply,Reply,NextStateName,NewStateData,Timeout}或{reply,Reply,NextStateName,NewStateData,hibernate},則Reply將給回到From做爲sync_send_event/2,3的返回值。而後gen_fsm繼續執行,當前狀態名稱設置爲NextStateName,而且可能更新狀態數據NewStateData。有關Timeout和hibernate的說明,請參閱Module:init/1。
    若是函數返回{next_state,NextStateName,NewStateData},{next_state,NextStateName,NewStateData,Timeout}或{next_state,NextStateName,NewStateData,hibernate},gen_fsm將繼續使用NewStateData在NextStateName中執行。必須使用gen_fsm:reply/2明確給出對From的任何回覆。
    若是函數返回{stop,Reason,Reply,NewStateData},則回覆將返回From。若是函數返回{stop,Reason,NewStateData},則必須使用gen_fsm:reply/2顯式給出對From的任何回覆。而後gen_fsm將調用Module:terminate(Reason,NewStateData)並終止。         
 
Module:handle_sync_event(Event, From, StateName, StateData) -> Result
    Types:
        Event = term()
        From = {pid(),Tag}
        StateName = atom()
        StateData = term()
        Result = {reply,Reply,NextStateName,NewStateData}
        | {reply,Reply,NextStateName,NewStateData,Timeout}
        | {reply,Reply,NextStateName,NewStateData,hibernate}
        | {next_state,NextStateName,NewStateData}
        | {next_state,NextStateName,NewStateData,Timeout}
        | {next_state,NextStateName,NewStateData,hibernate}
        | {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData}
         Reply = term()
         NextStateName = atom()
         NewStateData = term()
         Timeout = int()>0 | infinity
         Reason = term()
    每當gen_fsm接收到使用gen_fsm:sync_send_all_state_event/2,3發送的事件時,將調用此函數來處理該事件。
    StateName是gen_fsm的當前狀態名稱。
    有關其餘參數和可能的返回值的說明,請參閱Module:StateName/3。
 
Module:handle_info(Info, StateName, StateData) -> Result
    Types:
        Info = term()
        StateName = atom()
        StateData = term()
        Result = {next_state,NextStateName,NewStateData}
        | {next_state,NextStateName,NewStateData,Timeout}
        | {next_state,NextStateName,NewStateData,hibernate}
        | {stop,Reason,NewStateData}
        NextStateName = atom()
        NewStateData = term()
        Timeout = int()>0 | infinity
        Reason = normal | term()
    當gen_fsm接收到除同步或異步事件(或系統消息)以外的任何其餘消息時,將調用此函數。
    Info是收到的消息。
    有關其餘參數和可能的返回值的說明,請參閱Module:StateName/2。
 
Module:terminate(Reason, StateName, StateData)
    Types:
        Reason = normal | shutdown | {shutdown,term()} | term()
        StateName = atom()
        StateData = term()
    當gen_fsm即將終止時,該函數被gen_fsm調用。它應該與Module:init/1相反,並進行任何須要的清理。返回時,gen_fsm以Reason結束。返回值被忽略。
    Reason是表示中止緣由的術語,StateName是當前狀態名稱,StateData是gen_fsm的狀態數據。
    Reason取決於gen_fsm爲什麼終止。若是是由於另外一個回調函數返回了一箇中止元組{stop,..},則Reason將具備該元組中指定的值。若是是因爲失敗,則Reason是錯誤緣由。
    若是gen_fsm是監督樹的一部分而且由其主管命令終止,則若是知足如下條件,則將使用Reason = shutdown調用此函數:
    gen_fsm已被設置爲捕獲退出信號,而且監督者的子規範中定義的關閉策略是整數超時值,而不是brutal_kill。
    即便gen_fsm不是監督樹的一部分,若是它從其父級接收到「EXIT」消息,也將調用該函數。Reason與「EXIT」消息中的緣由相同。
    不然,gen_fsm將當即終止。
    請注意,除了正常,關閉或{shutdown,Term}以外的任何其餘緣由,假定gen_fsm因爲錯誤而終止,而且使用error_logger:format/2發出錯誤報告。 
 
Module:code_change(OldVsn, StateName, StateData, Extra) -> {ok, NextStateName, NewStateData}
    Types:
        OldVsn = Vsn | {down, Vsn}
        Vsn = term()
        StateName = NextStateName = atom()
        StateData = NewStateData = term()
        Extra = term()
    當gen_fsm在發佈升級/降級期間更新其內部狀態數據時,即在appup文件中給出Change= {advanced,Extra}的指令{update,Module,Change,...}時,將調用此函數。 見OTP設計原則。
    在升級的狀況下,OldVsn是Vsn,在降級的狀況下,OldVsn是{down,Vsn}。 Vsn由舊版本的回調模塊Module的vsn屬性定義。 若是未定義此類屬性,則版本是BEAM文件的校驗和。
    StateName是當前狀態名稱,StateData是gen_fsm的內部狀態數據。
    Extra從更新指令的{advanced,Extra}部分按原樣傳遞。
    該函數應返回新的當前狀態名稱和更新的內部數據。
 
Module:format_status(Opt, [PDict, StateData]) -> Status
    Types:
        Opt = normal | terminate
        PDict = [{Key, Value}]
        StateData = term()
        Status = term()
    請注意,該回調可選,因此回調模塊不須要導出它,這個回調模塊提供一個默認實現,該函數返回回調模塊狀態。
 
    在如下狀況下,gen_fsm進程會調用此函數:
    調用sys:get_status/1,2之一以獲取gen_fsm狀態。對於這種狀況,Opt設置爲原子normal。
    gen_fsm異常終止並記錄錯誤。對於這種狀況,選項設置爲原子terminate。
    此函數可用於自定義這些狀況的gen_fsm狀態的形式和外觀。但願自定義sys:get_status/1,2返回值以及其狀態如何在終止錯誤日誌中出現的回調模塊導出format_status/2的實例,該實例返回描述gen_fsm當前狀態的術語。
    PDict是gen_fsm的進程字典的當前值。
    StateData是gen_fsm的內部狀態數據。
    該函數應返回Status,這是一個定製gen_fsm當前狀態和狀態詳細信息的術語。狀態能夠採起的形式沒有限制,但對於sys:get_status/1,2狀況(當Opt是normal時),Status值的推薦形式爲[{data,[{「StateData」,Term}]其中Term提供gen_fsm狀態數據的相關詳細信息。不須要遵循此建議,但這樣作會使回調模塊狀態與sys:get_status/1,2返回值的其他部分保持一致。
    此函數的一個用途是返回緊湊的替代狀態數據表示,以免在日誌文件中打印大的狀態術語。
相關文章
相關標籤/搜索