openCore.StdopenAsync.StdopenBroker_protocolmoduleAscii_table=Textutils.Std.Ascii_tablelethost_and_port()=Command.Spec.(empty+>Common.host_arg()+>Common.port_arg())(* Shutdown command *****************************************)letshutdown=Common.with_rpc_conn(funconn->Rpc.Rpc.dispatch_exnshutdown_rpcconn())letshutdown_cmd=Command.async_basic(host_and_port())~summary:"Shut the broker down"(funhostport()->shutdown~host~port)(* Publish command ******************************************)letpublish~topic~text=Common.with_rpc_conn(funconn->letfrom=Option.value_exn(Sys.getenv"USER")~message:"Unknown username"|>String.strip|>Username.of_stringinRpc.Rpc.dispatch_exnpublish_rpcconn{Message.text;topic;from;time=Time.now()})letpub_cmd=Command.async_basic~summary:"publish a single value"Command.Spec.((host_and_port())+>anon("<topic>"%:Arg_type.createTopic.of_string)+>anon("<text>"%:string))(funhostporttopictext()->publish~host~port~topic~text)(* Subscribe command ****************************************)letsubscribe~topic=Common.with_rpc_conn(funconn->letclear_string="\027[H\027[2J"inRpc.Pipe_rpc.dispatchsubscribe_rpcconntopic>>=function|Errorerr->Error.raiseerr|Ok(Errors)->eprintf"subscribe failed: %s\n"s;return()|Ok(Ok(pipe,_id))->Pipe.iterpipe~f:(funmsg->printf"%s%s\n%!"clear_stringmsg.Message.text;return()))letsub_cmd=Command.async_basic~summary:"subscribe to a topic"Command.Spec.(host_and_port()+>anon("<topic>"%:Arg_type.createTopic.of_string))(funhostporttopic()->subscribe~host~port~topic)(* Dump command *********************************************)letsexp_print_dumpdump=printf"%s\n"(Dump.sexp_of_tdump|>Sexp.to_string_hum)letcol=Ascii_table.Column.createletcolumns=[col"topic"(fund->Topic.to_stringd.Dump.message.Message.topic);col"text"(fund->d.Dump.message.Message.text)~max_width:25;col"#sub"(fund->Int.to_stringd.Dump.num_subscribers);col"time"(fund->Time.to_sec_stringd.Dump.message.Message.time)]lettable_print_dumpdump=printf"%s%!"(Ascii_table.to_string~display:Ascii_table.Display.line~limit_width_to:72columnsdump)letdump~sexp=Common.with_rpc_conn(funconn->Rpc.Rpc.dispatch_exndump_rpcconn()>>=fundump->(ifsexpthensexp_print_dumpdumpelsetable_print_dumpdump);return())letdump_cmd=Command.async_basic~summary:"Get a full dump of the broker's state"Command.Spec.(host_and_port()+>flag"-sexp"no_arg~doc:" Show as raw s-expression")(funhostportsexp()->dump~host~port~sexp)(* Clear command ********************************************)letcleartopic=Common.with_rpc_conn(funconn->Rpc.Rpc.dispatch_exnclear_rpcconntopic)letclear_cmd=Command.async_basic~summary:"Clear out a given topic"Command.Spec.(host_and_port()+>anon("<topic>"%:Arg_type.createTopic.of_string))(funhostporttopic()->cleartopic~host~port)(* Execution of final command *******************************)let()=Command.run(Command.group~summary:"Utilities for interacting with message broker"["publish",pub_cmd;"subscribe",sub_cmd;"dump",dump_cmd;"shutdown",shutdown_cmd;"clear",clear_cmd])