[solved]Two async rpc call doesn't seems work concurrency as expected

I just extended @Yaron_Minsky 's example hello world rpc to two async rpc call as follows:

open Core
open Async
open Yojson

let logger : Log.t = Log.create ~level:`Debug
    ~output:[(Log.Output.file `Text ~filename:"log.txt")] ~on_error:`Raise

let get_info ~host ~port =
  Log.debug logger "combo begin: %s\n" (Time.to_string (Time.now ()));

  let%bind weather = 
    Common.with_rpc_conn (fun conn ->    
        let%map response = Rpc.Rpc.dispatch_exn Weather_protocol.weather_rpc  conn "tokyo" in
        response)
      ~host ~port
  in
  let%map country =
    Common.with_rpc_conn (fun conn ->    
        let%map response = Rpc.Rpc.dispatch_exn Country_protocol.country_rpc conn "tokyo" in
        response)
      ~host ~port:8128
  in
  let total =  `Assoc [ ("weahter", `String weather); ("country", `String country)] in
  let total_json = Yojson.Basic.pretty_to_string total in
  Log.debug logger "combo end: %s\n" (Time.to_string (Time.now ()));
  printf "%s\n%!" total_json

let command =
  Command.async'
    ~summary:"combo client"
    Command.Let_syntax.(
      [%map_open
        let (host, port) = Common.ranker_host_port_pair in
        fun () -> get_info ~port ~host
      ])

let () =  Command.run command

The Weather_protocol.weather_rpc would sleep 2.5 seconds before response, while the Country_protocol.country_rpc would sleep 3.5 seconds.

But this program turns out to be costing 6 seconds as the log.txt shows

2018-01-04 18:03:23.632970+08:00 Debug combo begin: 2018-01-04 18:03:23.629789+08:00

2018-01-04 18:03:29.646746+08:00 Debug combo end: 2018-01-04 18:03:29.646739+08:00

Bind puts things in sequence. You can put them in parallel if you want, though.

open Core
open Async
open Yojson

let logger : Log.t = Log.create ~level:`Debug
    ~output:[(Log.Output.file `Text ~filename:"log.txt")] ~on_error:`Raise

let get_info ~host ~port =
  Log.debug logger "combo begin: %s\n" (Time.to_string (Time.now ()));

  let%map weather = 
    Common.with_rpc_conn (fun conn ->    
        let%map response = Rpc.Rpc.dispatch_exn Weather_protocol.weather_rpc  conn "tokyo" in
        response)
      ~host ~port
  and country =
    Common.with_rpc_conn (fun conn ->    
        let%map response = Rpc.Rpc.dispatch_exn Country_protocol.country_rpc conn "tokyo" in
        response)
      ~host ~port:8128
  in
  let total =  `Assoc [ ("weahter", `String weather); ("country", `String country)] in
  let total_json = Yojson.Basic.pretty_to_string total in
  Log.debug logger "combo end: %s\n" (Time.to_string (Time.now ()));
  printf "%s\n%!" total_json

let command =
  Command.async'
    ~summary:"combo client"
    Command.Let_syntax.(
      [%map_open
        let (host, port) = Common.ranker_host_port_pair in
        fun () -> get_info ~port ~host
      ])

let () =  Command.run command

3 Likes