summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Feuer <mfeuer@jaguarlandrover.com>2015-03-24 16:56:18 -0700
committerMagnus Feuer <mfeuer@jaguarlandrover.com>2015-03-24 16:56:18 -0700
commit0363780cff7b3f970ba09693b6a3255621d3f433 (patch)
tree6fa55dcdde6f6b06b43eceba0cc1461bfc27eb8b
parentb6d4329eeed6a8c9db29220dbc43af4544bfe9ce (diff)
downloadrvi_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.erl156
-rw-r--r--components/service_edge/src/service_edge_rpc.erl78
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)} ] }.
%%