module Dynamic_port_writer:sig
..end
This is used to fork+exec a child process that will create create a TCP server that listens to a dynamically chosen port, and to make the port number available in the parent process once the child process is listening on the port.
Here is the intended usage:
1. The parent create
s a Dynamic_port_writer.t
value together with a deferred that
will eventually be determined with the port assigned to the child process by the OS.
2. The parent communicates the Dynamic_port_writer.t
value to a child it has
spawned. This can happen in a number of ways,
to_string
and either arg
or of_string
.Tcp.Server.create
with the value returned by where_to_listen
.
Once the server created in step (3) is listening on its OS-assigned port, the parent's deferred obtained in step (1) will soon become determined with the value of the port.
Code for the parent process would look something like:
Dynamic_port_writer.create ()
>>= fun (dynamic_port_writer, port_d) ->
Unix.fork_exec ~prog
~args:([ prog ]
@ Dynamic_port_writer.flag_args dynamic_port_writer
@ [ ... other args ... ])
()
>>= fun _child_pid ->
port_d
>>= fun r ->
let `Port port = ok_exn r in
Tcp.connect (Tcp.to_host_and_port "localhost" port)
>>= fun (_, reader, writer) ->
...
Code for the Command.t
for the child process would look something like:
Command.basic
~summary:"child"
(Command.Spec.(empty +> Dynamic_port_writer.flag))
(fun dynamic_port_writer () ->
...
Tcp.Server.create
(Dynamic_port_writer.where_to_listen dynamic_port_writer)
(fun _ reader writer -> ...))
type
t
include Stringable
val create : unit ->
(t *
[ `Port of int ] Core.Std.Or_error.t Import.Deferred.t)
Import.Deferred.t
val where_to_listen : t ->
(Import.Socket.Address.Inet.t, int) Tcp.Where_to_listen.t
val arg : t Core.Std.Command.Spec.Arg_type.t
Command
.val flag : t Core.Std.Command.Spec.param
t
from parent to child by including flag_args t
in the command-line
arguments and using flag
in the Command.t
in the child.val flag_args : t -> string list
val t_of_sexp : Sexplib.Sexp.t -> t
val sexp_of_t : t -> Sexplib.Sexp.t
val bin_t : t Bin_prot.Type_class.t
val bin_read_t : t Bin_prot.Read_ml.reader
val bin_read_t_ : t Bin_prot.Unsafe_read_c.reader
val bin_read_t__ : (int -> t) Bin_prot.Unsafe_read_c.reader
val bin_reader_t : t Bin_prot.Type_class.reader
val bin_size_t : t Bin_prot.Size.sizer
val bin_write_t : t Bin_prot.Write_ml.writer
val bin_write_t_ : t Bin_prot.Unsafe_write_c.writer
val bin_writer_t : t Bin_prot.Type_class.writer
Command
.t
from parent to child by including flag_args t
in the command-line
arguments and using flag
in the Command.t
in the child.