this repo has no description
at main 3.2 kB view raw
1open Swim.Types 2module Cluster = Swim.Cluster 3 4external env_cast : 'a -> 'b = "%identity" 5 6type node_result = { 7 port : int; 8 messages_sent : int; 9 messages_received : int; 10 members_seen : int; 11 memory_bytes : int; 12 elapsed_sec : float; 13} 14 15let result_to_json r = 16 Printf.sprintf 17 {|{"port":%d,"messages_sent":%d,"messages_received":%d,"members_seen":%d,"memory_bytes":%d,"elapsed_sec":%.3f}|} 18 r.port r.messages_sent r.messages_received r.members_seen r.memory_bytes 19 r.elapsed_sec 20 21let make_config ~port ~name = 22 { 23 default_config with 24 bind_addr = "\127\000\000\001"; 25 bind_port = port; 26 node_name = Some name; 27 protocol_interval = 0.2; 28 probe_timeout = 0.1; 29 suspicion_mult = 2; 30 secret_key = String.make 16 'k'; 31 cluster_name = ""; 32 encryption_enabled = false; 33 } 34 35let run_node ~env ~port ~peers ~duration_sec = 36 Gc.full_major (); 37 let mem_before = (Gc.stat ()).Gc.live_words * (Sys.word_size / 8) in 38 let start_time = Unix.gettimeofday () in 39 40 Eio.Switch.run @@ fun sw -> 41 let config = make_config ~port ~name:(Printf.sprintf "node-%d" port) in 42 let env_wrap = { stdenv = env; sw } in 43 44 match Cluster.create ~sw ~env:env_wrap ~config with 45 | Error `Invalid_key -> Unix._exit 1 46 | Ok cluster -> 47 Cluster.start cluster; 48 49 List.iter 50 (fun peer_port -> 51 if peer_port <> port then 52 let peer_id = 53 node_id_of_string (Printf.sprintf "node-%d" peer_port) 54 in 55 let peer_addr = 56 `Udp (Eio.Net.Ipaddr.of_raw "\127\000\000\001", peer_port) 57 in 58 let peer = make_node_info ~id:peer_id ~addr:peer_addr ~meta:"" in 59 Cluster.add_member cluster peer) 60 peers; 61 62 Eio.Time.sleep env#clock duration_sec; 63 64 let s = Cluster.stats cluster in 65 let members = Cluster.members cluster in 66 67 Gc.full_major (); 68 let mem_after = (Gc.stat ()).Gc.live_words * (Sys.word_size / 8) in 69 let elapsed = Unix.gettimeofday () -. start_time in 70 71 let result = 72 { 73 port; 74 messages_sent = s.msgs_sent; 75 messages_received = s.msgs_received; 76 members_seen = List.length members; 77 memory_bytes = max 0 (mem_after - mem_before); 78 elapsed_sec = elapsed; 79 } 80 in 81 82 print_endline (result_to_json result); 83 flush stdout; 84 Unix._exit 0 85 86let parse_peers s = 87 String.split_on_char ',' s 88 |> List.filter (fun s -> String.length s > 0) 89 |> List.map int_of_string 90 91let () = 92 let port = ref 0 in 93 let peers_str = ref "" in 94 let duration_sec = ref 10.0 in 95 96 let specs = 97 [ 98 ("-port", Arg.Set_int port, "Port to bind to (required)"); 99 ("-peers", Arg.Set_string peers_str, "Comma-separated peer ports"); 100 ("-duration", Arg.Set_float duration_sec, "Duration in seconds"); 101 ] 102 in 103 Arg.parse specs (fun _ -> ()) "SWIM Single Node Benchmark"; 104 105 if !port = 0 then ( 106 Printf.eprintf "Error: -port is required\n"; 107 exit 1); 108 109 let peers = parse_peers !peers_str in 110 111 Eio_main.run @@ fun env -> 112 let env = env_cast env in 113 run_node ~env ~port:!port ~peers ~duration_sec:!duration_sec