- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
waiting_for_data(info, {Driver,Socket,Data},
#state{socket=Socket, driver=Driver, driver_mod=DriverMod, peer=Peer, control=Control, list=List} = State) ->
%% The meat of the whole project: process a function call and return
%% the data
try erlang:binary_to_term(Data) of
{{CallType,M,F,A}, Caller} when CallType =:= call; CallType =:= async_call ->
{ModVsnAllowed, RealM} = check_module_version_compat(M),
case check_if_module_allowed(RealM, Control, List) of
true ->
case ModVsnAllowed of
true ->
WorkerPid = erlang:spawn(?MODULE, call_worker, [CallType, RealM, F, A, Caller, Socket, Driver, DriverMod]),
?log(debug, "event=call_received driver=~s socket=\"~s\" peer=\"~s\" caller=\"~p\" worker_pid=\"~p\"",
[Driver, gen_rpc_helper:socket_to_string(Socket), gen_rpc_helper:peer_to_string(Peer), Caller, WorkerPid]),
{keep_state_and_data, gen_rpc_helper:get_inactivity_timeout(?MODULE)};
false ->
?log(debug, "event=incompatible_module_version driver=~s socket=\"~s\" method=~s module=~s",
[Driver, gen_rpc_helper:socket_to_string(Socket), CallType, RealM]),
waiting_for_data(info, {CallType, Caller, {badrpc,incompatible}}, State)
end;
false ->
?log(debug, "event=request_not_allowed driver=~s socket=\"~s\" control=~s method=~s module=~s",
[Driver, gen_rpc_helper:socket_to_string(Socket), Control, CallType, RealM]),
waiting_for_data(info, {CallType, Caller, {badrpc,unauthorized}}, State)
end;
{cast, _M, _F, _A} = Cast ->
handle_cast(Cast, State),
{keep_state_and_data, gen_rpc_helper:get_inactivity_timeout(?MODULE)};
BatchCast when is_list(BatchCast) ->
[handle_cast(Cast, State) || Cast <- BatchCast],
{keep_state_and_data, gen_rpc_helper:get_inactivity_timeout(?MODULE)};
{abcast, Name, Msg} ->
_Result = case check_if_module_allowed(erlang, Control, List) of
true ->
?log(debug, "event=abcast_received driver=~s socket=\"~s\" peer=\"~s\" process=~s message=\"~p\"",
[Driver, gen_rpc_helper:socket_to_string(Socket), gen_rpc_helper:peer_to_string(Peer), Name, Msg]),
Msg = erlang:send(Name, Msg);
false ->
?log(debug, "event=request_not_allowed driver=~s socket=\"~s\" control=~s method=~s",
[Driver, gen_rpc_helper:socket_to_string(Socket), Control, abcast])
end,
{keep_state_and_data, gen_rpc_helper:get_inactivity_timeout(?MODULE)};
{sbcast, Name, Msg, Caller} ->
Reply = case check_if_module_allowed(erlang, Control, List) of
true ->
?log(debug, "event=sbcast_received driver=~s socket=\"~s\" peer=\"~s\" process=~s message=\"~p\"",
[Driver, gen_rpc_helper:socket_to_string(Socket), gen_rpc_helper:peer_to_string(Peer), Name, Msg]),
case erlang:whereis(Name) of
undefined -> error;
Pid -> Msg = erlang:send(Pid, Msg), success
end;
false ->
?log(debug, "event=request_not_allowed driver=~s socket=\"~s\" control=~s method=~s",
[Driver, gen_rpc_helper:socket_to_string(Socket), Control, sbcast]),
error
end,
waiting_for_data(info, {sbcast, Caller, Reply}, State);
ping ->
?log(debug, "event=ping_received driver=~s socket=\"~s\" peer=\"~s\" action=ignore",
[Driver, gen_rpc_helper:socket_to_string(Socket), gen_rpc_helper:peer_to_string(Peer)]),
{keep_state_and_data, gen_rpc_helper:get_inactivity_timeout(?MODULE)};
OtherData ->
?log(debug, "event=erroneous_data_received driver=~s socket=\"~s\" peer=\"~s\" data=\"~p\"",
[Driver, gen_rpc_helper:socket_to_string(Socket), gen_rpc_helper:peer_to_string(Peer), OtherData]),
{stop, {badrpc,erroneous_data}, State}
catch
error:badarg ->
{stop, {badtcp,corrupt_data}, State}
end;
%% Handle the inactivity timeout gracefully
waiting_for_data(timeout, _Undefined, #state{socket=Socket, driver=Driver} = State) ->
?log(info, "message=timeout event=server_inactivity_timeout driver=~s socket=\"~s\" action=stopping",
[Driver, gen_rpc_helper:socket_to_string(Socket)]),
{stop, normal, State};
waiting_for_data(info, {DriverClosed, Socket} = Msg, #state{socket=Socket, driver_closed=DriverClosed} = State) ->
handle_event(info, Msg, waiting_for_data, State);
waiting_for_data(info, {DriverError, Socket, _Reason} = Msg, #state{socket=Socket, driver_error=DriverError} = State) ->
handle_event(info, Msg, waiting_for_data, State).
Срочно требуется учитель литературы, чтобы объяснить, что хотел сказать автор.