P2P: Introduce a worker dedicated to user events
This commit is contained in:
parent
a832c2069f
commit
bdb2d20f05
@ -1061,35 +1061,44 @@ module Make (P: PARAMS) = struct
|
|||||||
(fun (n, l) (point, _, _) -> if n = 0 then (n, l) else (n - 1, point :: l))
|
(fun (n, l) (point, _, _) -> if n = 0 then (n, l) else (n - 1, point :: l))
|
||||||
(50, []) |> snd
|
(50, []) |> snd
|
||||||
in
|
in
|
||||||
let rec available_events () =
|
let next_peer_event () =
|
||||||
|
let rec peer_events () =
|
||||||
let peers = PeerMap.bindings !connected in
|
let peers = PeerMap.bindings !connected in
|
||||||
let current_peers_evts =
|
let current_peers_evts =
|
||||||
List.map (fun (_, gid, p) ->
|
List.map begin function
|
||||||
Lwt_pipe.values_available p.reader >|= fun () -> gid, p.reader)
|
| _, Some gid, p -> Lwt_pipe.values_available p.reader >|= fun () -> gid, p.reader
|
||||||
peers
|
| _ -> Lwt_utils.never_ending
|
||||||
|
end peers
|
||||||
in
|
in
|
||||||
Lwt.choose [
|
Lwt.choose [
|
||||||
(LC.wait new_peer >>= fun _p -> available_events ());
|
(LC.wait new_peer >>= fun _p -> peer_events ());
|
||||||
Lwt.nchoose @@
|
Lwt.nchoose current_peers_evts;
|
||||||
(Lwt_pipe.values_available events >|= fun () -> None, events) :: current_peers_evts
|
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
let rec choose_event () =
|
peer_events () >>= fun evts ->
|
||||||
available_events () >>= fun evts ->
|
|
||||||
let nb_evts = List.length evts in
|
let nb_evts = List.length evts in
|
||||||
let gid, evtqueue = List.nth evts (Random.int nb_evts) in
|
let gid, evtqueue = List.nth evts (Random.int nb_evts) in
|
||||||
begin match gid with
|
lwt_debug "(%a) Processing event from %a" pp_gid my_gid pp_gid gid >|= fun () ->
|
||||||
| None -> lwt_debug "(%a) Processing event from main" pp_gid my_gid
|
|
||||||
| Some remote_gid -> lwt_debug "(%a) Processing event from %a" pp_gid my_gid pp_gid remote_gid
|
|
||||||
end >|= fun () ->
|
|
||||||
Lwt_pipe.pop_now_exn evtqueue
|
Lwt_pipe.pop_now_exn evtqueue
|
||||||
in
|
in
|
||||||
(* main internal event handling worker *)
|
let rec peers () =
|
||||||
let rec main () =
|
(* user event handling worker *)
|
||||||
|
Lwt.pick [
|
||||||
|
next_peer_event () ;
|
||||||
|
cancelation () >>= fun () -> Lwt.return Shutdown ;
|
||||||
|
] >>= fun event -> match event with
|
||||||
|
| Recv (peer, msg) -> Lwt_pipe.push messages (peer, msg) >>= peers
|
||||||
|
| msg -> Lwt_pipe.push events msg >>= peers
|
||||||
|
in
|
||||||
|
(* internal event handling worker *)
|
||||||
|
let rec admin () =
|
||||||
Lwt.pick
|
Lwt.pick
|
||||||
[ choose_event () ;
|
[ Lwt_pipe.pop events ;
|
||||||
cancelation () >>= fun () -> Lwt.return Shutdown ] >>= fun event ->
|
cancelation () >>= fun () -> Lwt.return Shutdown ] >>= fun event ->
|
||||||
match event with
|
match event with
|
||||||
|
| Recv _ ->
|
||||||
|
(* Invariant broken *)
|
||||||
|
Lwt.fail_with "admin: got a Recv message (broken invariant)"
|
||||||
| Disconnected peer ->
|
| Disconnected peer ->
|
||||||
debug "(%a) disconnected peer %a" pp_gid my_gid pp_gid peer.gid ;
|
debug "(%a) disconnected peer %a" pp_gid my_gid pp_gid peer.gid ;
|
||||||
(* remove it from the tables *)
|
(* remove it from the tables *)
|
||||||
@ -1097,7 +1106,7 @@ module Make (P: PARAMS) = struct
|
|||||||
if PeerMap.cardinal !connected < limits.min_connections then
|
if PeerMap.cardinal !connected < limits.min_connections then
|
||||||
LC.broadcast too_few_peers () ;
|
LC.broadcast too_few_peers () ;
|
||||||
incoming := PointMap.remove peer.point !incoming ;
|
incoming := PointMap.remove peer.point !incoming ;
|
||||||
main ()
|
admin ()
|
||||||
| Connected peer ->
|
| Connected peer ->
|
||||||
incoming := PointMap.remove peer.point !incoming ;
|
incoming := PointMap.remove peer.point !incoming ;
|
||||||
let update_infos () =
|
let update_infos () =
|
||||||
@ -1162,7 +1171,7 @@ module Make (P: PARAMS) = struct
|
|||||||
LC.broadcast too_many_peers () ;
|
LC.broadcast too_many_peers () ;
|
||||||
LC.broadcast new_peer peer
|
LC.broadcast new_peer peer
|
||||||
end ;
|
end ;
|
||||||
main ()
|
admin ()
|
||||||
| Contact ((addr, port), socket) ->
|
| Contact ((addr, port), socket) ->
|
||||||
(* we do not check the credentials at this stage, since they
|
(* we do not check the credentials at this stage, since they
|
||||||
could change from one connection to the next *)
|
could change from one connection to the next *)
|
||||||
@ -1170,7 +1179,7 @@ module Make (P: PARAMS) = struct
|
|||||||
|| PeerMap.mem_by_point (addr, port) !connected
|
|| PeerMap.mem_by_point (addr, port) !connected
|
||||||
|| BlackList.mem addr !black_list then
|
|| BlackList.mem addr !black_list then
|
||||||
LU.close socket >>= fun () ->
|
LU.close socket >>= fun () ->
|
||||||
main ()
|
admin ()
|
||||||
else
|
else
|
||||||
let canceler =
|
let canceler =
|
||||||
connect_to_peer
|
connect_to_peer
|
||||||
@ -1179,14 +1188,11 @@ module Make (P: PARAMS) = struct
|
|||||||
debug "(%a) incoming peer @@ %a:%d"
|
debug "(%a) incoming peer @@ %a:%d"
|
||||||
pp_gid my_gid Ipaddr.pp_hum addr port ;
|
pp_gid my_gid Ipaddr.pp_hum addr port ;
|
||||||
incoming := PointMap.add (addr, port) canceler !incoming ;
|
incoming := PointMap.add (addr, port) canceler !incoming ;
|
||||||
main ()
|
admin ()
|
||||||
| Bootstrap peer ->
|
| Bootstrap peer ->
|
||||||
let sample = bootstrap_peers () in
|
let sample = bootstrap_peers () in
|
||||||
Lwt.async (fun () -> peer.send (Advertise sample)) ;
|
Lwt.async (fun () -> peer.send (Advertise sample)) ;
|
||||||
main ()
|
admin ()
|
||||||
| Recv (peer, msg) ->
|
|
||||||
Lwt_pipe.push messages (peer, msg) >>=
|
|
||||||
main
|
|
||||||
| Peers peers ->
|
| Peers peers ->
|
||||||
List.iter
|
List.iter
|
||||||
(fun point ->
|
(fun point ->
|
||||||
@ -1199,7 +1205,7 @@ module Make (P: PARAMS) = struct
|
|||||||
known_peers := PeerMap.update point source !known_peers ;
|
known_peers := PeerMap.update point source !known_peers ;
|
||||||
LC.broadcast new_contact point)
|
LC.broadcast new_contact point)
|
||||||
peers ;
|
peers ;
|
||||||
main ()
|
admin ()
|
||||||
| Shutdown ->
|
| Shutdown ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
in
|
in
|
||||||
@ -1233,10 +1239,14 @@ module Make (P: PARAMS) = struct
|
|||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "(%a) maintenance" pp_gid my_gid)
|
(Format.asprintf "(%a) maintenance" pp_gid my_gid)
|
||||||
maintenance cancel in
|
maintenance cancel in
|
||||||
let main =
|
let peers_worker =
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "(%a) reception" pp_gid my_gid)
|
(Format.asprintf "(%a) peers" pp_gid my_gid)
|
||||||
main cancel in
|
peers cancel in
|
||||||
|
let admin =
|
||||||
|
Lwt_utils.worker
|
||||||
|
(Format.asprintf "(%a) admin" pp_gid my_gid)
|
||||||
|
admin cancel in
|
||||||
let unblock =
|
let unblock =
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "(%a) unblacklister" pp_gid my_gid)
|
(Format.asprintf "(%a) unblacklister" pp_gid my_gid)
|
||||||
@ -1282,7 +1292,7 @@ module Make (P: PARAMS) = struct
|
|||||||
(* stop accepting clients *)
|
(* stop accepting clients *)
|
||||||
cancel () >>= fun () ->
|
cancel () >>= fun () ->
|
||||||
(* wait for both workers to end *)
|
(* wait for both workers to end *)
|
||||||
Lwt.join [ welcome ; main ; maintenance ; unblock ;
|
Lwt.join [ welcome ; peers_worker ; admin ; maintenance ; unblock ;
|
||||||
discovery_answerer ; discovery_sender ] >>= fun () ->
|
discovery_answerer ; discovery_sender ] >>= fun () ->
|
||||||
(* properly shutdown all peers *)
|
(* properly shutdown all peers *)
|
||||||
let cancelers =
|
let cancelers =
|
||||||
|
Loading…
Reference in New Issue
Block a user