mirror of
https://github.com/ubf/ubf.git
synced 2025-12-06 15:45:30 +00:00
174 lines
6.0 KiB
Erlang
174 lines
6.0 KiB
Erlang
%%% The MIT License
|
|
%%%
|
|
%%% Copyright (C) 2011-2014 by Joseph Wayne Norton <norton@alum.mit.edu>
|
|
%%% Copyright (C) 2002 by Joe Armstrong
|
|
%%%
|
|
%%% Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
%%% of this software and associated documentation files (the "Software"), to deal
|
|
%%% in the Software without restriction, including without limitation the rights
|
|
%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
%%% copies of the Software, and to permit persons to whom the Software is
|
|
%%% furnished to do so, subject to the following conditions:
|
|
%%%
|
|
%%% The above copyright notice and this permission notice shall be included in
|
|
%%% all copies or substantial portions of the Software.
|
|
%%%
|
|
%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
%%% THE SOFTWARE.
|
|
|
|
-module(stateful_plugin).
|
|
-behaviour(ubf_plugin_stateful).
|
|
|
|
-include("ubf.hrl").
|
|
-include("ubf_plugin_stateful.hrl").
|
|
|
|
-export([info/0, description/0, keepalive/0]).
|
|
-export([managerStart/1, managerRestart/2, managerRpc/2]).
|
|
-export([handlerStart/2, handlerStop/3, handlerRpc/4, handlerRpc/1]).
|
|
|
|
-export([client_breaks_req01/0, client_timeout_req03/1]).
|
|
-export([server_breaks_req01/0, server_timeout_req03/1, server_crash_req05/0]).
|
|
|
|
-import(ubf_plugin_handler, [ask_manager/2]).
|
|
|
|
%% NOTE the following two lines
|
|
-compile({parse_transform,contract_parser}).
|
|
-add_contract("./test/eunit/stateful_plugin").
|
|
-add_types({types_plugin, [ubf_contract_res,ubf_contract_req,ubf_description_res,ubf_description_req,ubf_info_res,ubf_info_req]}).
|
|
-add_types({types_plugin, [ubf_keepalive_res,ubf_keepalive_req]}).
|
|
-add_types({types_plugin, [timeout]}).
|
|
-add_types({types_plugin, [server_crash_res05,server_crash_req05,
|
|
server_timeout_res03,server_timeout_req03,
|
|
server_breaks_res01,server_breaks_req01,
|
|
client_timeout_res03,client_timeout_req03,
|
|
client_breaks_res01,client_breaks_req01,
|
|
manager_rpc_req01,manager_rpc_req02]}).
|
|
-add_types({types_plugin, [restart_res,restart_req,server_crash_res06,
|
|
server_crash_req06,server_timeout_res04,
|
|
server_timeout_req04,server_breaks_res02,
|
|
server_breaks_req02,client_timeout_res04,
|
|
client_timeout_req04,client_breaks_res02,
|
|
client_breaks_req02,manager_rpc_res01,
|
|
manager_rpc_res02]}).
|
|
|
|
|
|
%% records
|
|
|
|
%% state
|
|
-record(state, {
|
|
}).
|
|
|
|
%% managerState
|
|
-record(managerState, {
|
|
inc=0
|
|
}).
|
|
|
|
|
|
info() ->
|
|
"I am a stateful server".
|
|
|
|
description() ->
|
|
"An stateful server programmed by UBF".
|
|
|
|
keepalive() ->
|
|
ok.
|
|
|
|
|
|
%% @spec managerStart(Args::list(any())) ->
|
|
%% {ok, ManagerStateData::term()} | {error, Reason::any()}
|
|
%% @doc start manager
|
|
managerStart(_) ->
|
|
ManagerStateData = #managerState{},
|
|
{ok,ManagerStateData}.
|
|
|
|
%% @spec managerRestart(Args::list(any()), ManagerPid::pid()) ->
|
|
%% ok | {error, Reason::any()}
|
|
%% @doc restart manager
|
|
managerRestart(Args,ManagerPid) ->
|
|
ask_manager(ManagerPid,{restartManager, Args}).
|
|
|
|
|
|
%% @spec managerRpc(Event::any(), ManagerStateData::term()) ->
|
|
%% {ok | {ok,term()} | error | {error, Reason::any()}, NewManagerStateData::term()}
|
|
%% @doc rpc manager
|
|
managerRpc({restartManager,Args},ManagerStateData)
|
|
when is_record(ManagerStateData,managerState) ->
|
|
managerStart(Args);
|
|
managerRpc(change_state, _ManagerStateData) ->
|
|
{ok, #managerState{inc=1}}.
|
|
|
|
|
|
|
|
%% @spec handlerStart(Args::list(any()), ManagerPid::pid()) ->
|
|
%% {accept, Reply::any(), StateName::atom(), StateData::term()} | {reject, Reason::any()}
|
|
%% @doc start handler
|
|
handlerStart(_Args,_ManagerPid) ->
|
|
{accept,ok,start,#state{}}.
|
|
|
|
%% @spec handlerStop(Pid::pid(), Reason::any(), ManagerStateData::term()) -> NewManagerStateData::term()
|
|
%% @doc stop handler event
|
|
handlerStop(_Pid,_Reason,ManagerStateData)
|
|
when is_record(ManagerStateData,managerState) ->
|
|
ManagerStateData.
|
|
|
|
|
|
%% @spec handlerRpc(StateName::atom(), Event::any(), StateData::term(), ManagerPid::pid()) ->
|
|
%% {Reply::any(), NextStateName::atom(), NewStateData::term()}
|
|
%% @doc rpc handler
|
|
handlerRpc(StateName,manager_rpc_req01,StateData,ManagerPid) ->
|
|
ok = ask_manager(ManagerPid, change_state),
|
|
{manager_rpc_res01,StateName,StateData};
|
|
handlerRpc(StateName,Event,StateData,_ManagerPid) ->
|
|
{handlerRpc(Event),StateName,StateData}.
|
|
|
|
|
|
%% @spec handlerRpc(Event::any()) ->
|
|
%% Reply::any()
|
|
%% @doc rpc handler
|
|
handlerRpc(Event)
|
|
when Event==client_breaks_req01
|
|
; Event==server_breaks_req01
|
|
; Event==server_crash_req05
|
|
->
|
|
?MODULE:Event();
|
|
handlerRpc({Event,Timeout})
|
|
when Event==client_timeout_req03
|
|
; Event==server_timeout_req03
|
|
->
|
|
?MODULE:Event(Timeout);
|
|
handlerRpc(Event)
|
|
when Event==info; Event==description ->
|
|
?S(?MODULE:Event());
|
|
handlerRpc(Event)
|
|
when Event==keepalive ->
|
|
?MODULE:Event();
|
|
handlerRpc(Event) ->
|
|
{Event, not_implemented}.
|
|
|
|
|
|
%%%----------------------------------------------------------------------
|
|
%%% Implementation functions
|
|
%%%----------------------------------------------------------------------
|
|
|
|
client_breaks_req01() ->
|
|
exit(client_breaks_req01_should_not_be_called).
|
|
|
|
client_timeout_req03(Timeout) ->
|
|
timer:sleep(Timeout),
|
|
client_timeout_res03.
|
|
|
|
server_breaks_req01() ->
|
|
server_breaks_res01_with_this_response.
|
|
|
|
server_timeout_req03(Timeout) ->
|
|
timer:sleep(Timeout),
|
|
server_timeout_res03.
|
|
|
|
server_crash_req05() ->
|
|
exit(server_crash_res05_with_this_response).
|