diff options
author | Magnus Feuer <mfeuer@jaguarlandrover.com> | 2015-03-24 16:56:18 -0700 |
---|---|---|
committer | Magnus Feuer <mfeuer@jaguarlandrover.com> | 2015-03-24 16:56:18 -0700 |
commit | 0363780cff7b3f970ba09693b6a3255621d3f433 (patch) | |
tree | 6fa55dcdde6f6b06b43eceba0cc1461bfc27eb8b | |
parent | b6d4329eeed6a8c9db29220dbc43af4544bfe9ce (diff) | |
download | rvi_core-0363780cff7b3f970ba09693b6a3255621d3f433.tar.gz |
Try to fix issue #16 with a somewhat ugly hack
-rw-r--r-- | components/data_link_bert_rpc/src/data_link_bert_rpc_rpc.erl | 156 | ||||
-rw-r--r-- | components/service_edge/src/service_edge_rpc.erl | 78 |
2 files changed, 129 insertions, 105 deletions
diff --git a/components/data_link_bert_rpc/src/data_link_bert_rpc_rpc.erl b/components/data_link_bert_rpc/src/data_link_bert_rpc_rpc.erl index 6b59352..c8fe558 100644 --- a/components/data_link_bert_rpc/src/data_link_bert_rpc_rpc.erl +++ b/components/data_link_bert_rpc/src/data_link_bert_rpc_rpc.erl @@ -65,7 +65,8 @@ init_rvi_component() -> ok; _ -> - ?info("data_link_bert_rpc_rpc:init_rvi_component(): exo_http_opts not specified. Gen Server only"), + ?info("data_link_bert_rpc_rpc:init_rvi_component(): " + "exo_http_opts not specified. Gen Server only"), ok end; @@ -270,58 +271,62 @@ handle_socket(FromPid, PeerIP, PeerPort, data, %% a service announce %% FIXME: Validate certificate and signature before continuing. - case connection_manager:find_connection_by_pid(FromPid) of - not_found -> - ?info("data_link_bert:authorize(): New connection!"), - connection_manager:add_connection(NRemoteAddress, NRemotePort, FromPid), - ?debug("data_link_bert:authorize(): Sending authorize."), - Res = connection:send(FromPid, - { authorize, - 1, LocalAddress, LocalPort, rvi_binary, - {certificate, {}}, { signature, {}}}), - ?debug("data_link_bert:authorize(): Sending authorize: ~p", [ Res]), - ok; - _ -> ok - end, - - %% Send our own servide announcement to the remote server - %% that just authorized to us. - %% First grab all our services. - case rvi_common:send_component_request(service_discovery, get_local_services, [], - [ services ]) of - { ok, _, [ JSONSvc] } -> - %% Covnert to JSON structured typles. - LocalServices = - lists:foldl(fun({struct, JSONElem}, Acc) -> - [ proplists:get_value("service", JSONElem, undefined) | Acc]; - ({Service, _LocalAddress}, Acc) -> - [ Service | Acc ]; - (Elem, Acc) -> - [ Elem | Acc ] - end, - [], JSONSvc), - - %% Grab our local address. - { LocalAddress, LocalPort } = rvi_common:node_address_tuple(), - - %% Send an authorize back to the remote node - ?info("data_link_bert:authorize(): Announcing local services: ~p to remote ~p:~p", - [LocalServices, NRemoteAddress, NRemotePort]), + spawn_monitor( + fun() -> + case connection_manager:find_connection_by_pid(FromPid) of + not_found -> + ?info("data_link_bert:authorize(): New connection!"), + connection_manager:add_connection(NRemoteAddress, NRemotePort, FromPid), + ?debug("data_link_bert:authorize(): Sending authorize."), + Res = connection:send(FromPid, + { authorize, + 1, LocalAddress, LocalPort, rvi_binary, + {certificate, {}}, { signature, {}}}), + ?debug("data_link_bert:authorize(): Sending authorize: ~p", [ Res]), + ok; + _ -> ok + end, - connection:send(FromPid, - { service_announce, 2, available, - LocalServices, { signature, {}}}); - Err -> - ?warning("data_link_bert:authorize() Failed at authorize: ~p", - - [ Err ]), - ok - end, + %% Send our own servide announcement to the remote server + %% that just authorized to us. + %% First grab all our services. + case rvi_common:send_component_request(service_discovery, get_local_services, [], + [ services ]) of + { ok, _, [ JSONSvc] } -> + %% Covnert to JSON structured typles. + LocalServices = + lists:foldl(fun({struct, JSONElem}, Acc) -> + [ proplists:get_value("service", JSONElem, undefined) | Acc]; + ({Service, _LocalAddress}, Acc) -> + [ Service | Acc ]; + (Elem, Acc) -> + [ Elem | Acc ] + end, + [], JSONSvc), + + %% Grab our local address. + { LocalAddress, LocalPort } = rvi_common:node_address_tuple(), + + %% Send an authorize back to the remote node + ?info("data_link_bert:authorize(): Announcing local services: ~p to remote ~p:~p", + [LocalServices, NRemoteAddress, NRemotePort]), + + connection:send(FromPid, + { service_announce, 2, available, + LocalServices, { signature, {}}}); + + Err -> + ?warning("data_link_bert:authorize() Failed at authorize: ~p", + + [ Err ]), + ok + end, - %% Setup ping interval - gen_server:call(?SERVER, { setup_initial_ping, NRemoteAddress, NRemotePort, FromPid }), + %% Setup ping interval + gen_server:call(?SERVER, { setup_initial_ping, NRemoteAddress, NRemotePort, FromPid }) + end), ok; handle_socket(_FromPid, RemoteIP, RemotePort, data, @@ -340,11 +345,14 @@ handle_socket(_FromPid, RemoteIP, RemotePort, data, %% Register the received services with all relevant components RemoteNetworkAddress = RemoteIP ++ ":" ++ integer_to_list(RemotePort), - rvi_common:send_component_request(service_discovery, register_remote_services, - [ - {services, Services}, - {network_address, RemoteNetworkAddress} - ]), + spawn_monitor( + fun() -> + rvi_common:send_component_request(service_discovery, register_remote_services, + [ + {services, Services}, + {network_address, RemoteNetworkAddress} + ]) + end), ok; @@ -362,10 +370,14 @@ handle_socket(_FromPid, RemoteIP, RemotePort, data, %% Register the received services with all relevant components - rvi_common:send_component_request(service_discovery, unregister_remote_services_by_name, - [ - {services, Services} - ]), + spawn_monitor( + fun() -> + rvi_common:send_component_request(service_discovery, + unregister_remote_services_by_name, + [ + {services, Services} + ]) + end), ok; @@ -373,17 +385,23 @@ handle_socket(_FromPid, SetupIP, SetupPort, data, { receive_data, Data}, _ExtraArgs) -> %% ?info("data_link_bert:receive_data(): ~p", [ Data ]), ?debug("data_link_bert:receive_data(): SetupAddress: {~p, ~p}", [ SetupIP, SetupPort ]), - case - rvi_common:send_component_request(protocol, receive_message, - [ - { data, Data } - ]) of - { ok, _ } -> - ok; - Err -> - ?info("data_link_bert:receive_data(): Failed to send component request: ~p", - [ Err ]) - end, + + %% Start a process to avoid deadlock as described in issue #16 + spawn_monitor(fun() -> + case + rvi_common:send_component_request(protocol, receive_message, + [ + { data, Data } + ]) of + { ok, _ } -> + ok; + Err -> + ?info("data_link_bert:receive_data(): Failed to send component request: ~p", + [ Err ]) + end, + ok + end), + ok; diff --git a/components/service_edge/src/service_edge_rpc.erl b/components/service_edge/src/service_edge_rpc.erl index e8d98b5..e9b3535 100644 --- a/components/service_edge/src/service_edge_rpc.erl +++ b/components/service_edge/src/service_edge_rpc.erl @@ -199,42 +199,48 @@ handle_local_message(ServiceName, Timeout, Parameters) -> ?debug("service_edge_rpc:local_msg: timeout: ~p", [Timeout]), ?debug("service_edge_rpc:local_msg: parameters: ~p", [Parameters]), - case - %% - %% Authorize local message and retrieve a certificate / signature - %% that will be accepted by the receiving node that will deliver - %% the messaage to its locally connected service_name service. - %% - rvi_common:send_component_request(authorize, authorize_local_message, - [ - {service_name, ServiceName} - ], - [ certificate, signature ]) of - { ok, ok, [Certificate, Signature] } -> - - %% - %% Check if this is a local service by trying to resolve its service name. - %% If successful, just forward it to its service_name. - %% - case rvi_common:send_component_request(service_discovery, resolve_local_service, - [ - {service, ServiceName} - ], [ network_address ]) of - { ok, ok, [ NetworkAddress] } -> %% ServiceName is local. Forward message - ?debug("service_edge_rpc:local_msg(): Service is local. Forwarding."), - forward_message_to_local_service(ServiceName, NetworkAddress, Parameters); - - _ -> %% ServiceName is remote - %% Ask Schedule the request to resolve the network address - ?debug("service_edge_rpc:local_msg(): Service is remote. Scheduling."), - forward_message_to_scheduler(ServiceName, Timeout, Parameters, Certificate, Signature) - end; - - Err -> - ?warning(" service_edge_rpc:local_msg() Failed at authorize: ~p", - [ Err ]), - Err - end. + %% Workaround for issue #16 + + spawn_monitor( + fun() -> + case + %% + %% Authorize local message and retrieve a certificate / signature + %% that will be accepted by the receiving node that will deliver + %% the messaage to its locally connected service_name service. + %% + rvi_common:send_component_request(authorize, authorize_local_message, + [ + {service_name, ServiceName} + ], + [ certificate, signature ]) of + { ok, ok, [Certificate, Signature] } -> + + %% + %% Check if this is a local service by trying to resolve its service name. + %% If successful, just forward it to its service_name. + %% + case rvi_common:send_component_request(service_discovery, resolve_local_service, + [ + {service, ServiceName} + ], [ network_address ]) of + { ok, ok, [ NetworkAddress] } -> %% ServiceName is local. Forward message + ?debug("service_edge_rpc:local_msg(): Service is local. Forwarding."), + forward_message_to_local_service(ServiceName, NetworkAddress, Parameters); + + _ -> %% ServiceName is remote + %% Ask Schedule the request to resolve the network address + ?debug("service_edge_rpc:local_msg(): Service is remote. Scheduling."), + forward_message_to_scheduler(ServiceName, Timeout, Parameters, Certificate, Signature) + end; + + Err -> + ?warning(" service_edge_rpc:local_msg() Failed at authorize: ~p", + [ Err ]), + Err + end + end), + { ok, [ { status, rvi_common:json_rpc_status(ok)} ] }. %% |