Module Procord_protocol

module Procord_protocol: sig .. end
Communication protocol between workers and main programs.


Errors


type error = 
| E_task_not_supported
| E_unexpected_message
| E_ill_formed_message
| E_message_too_long
| E_disconnected
| E_invalid_print_destination
Errors from workers and protocol errors.
exception Error of error
An error has occurred.
val error : error -> 'a
Raise an error.
val error_message : error -> string
Return a string explaining an error in English.

Messages


type custom_destination = char 
Custom destination identifiers.

Custom destinations are identified by a single character which should not be 'O' nor 'E'. You can typically use '0', '1', ..., '9'.

type print_destination = 
| D_stdout
| D_stderr
| D_custom of custom_destination
Possible destinations when sending messages to print.

Possible values are:


type message = 
| M_none
| M_value of string (*Serialized input or output.*)
| M_task_name of string
| M_exception of string (*Serialized exception.*)
| M_unknown_exception of string (*Exception as a string using Printexc.*)
| M_error of error
| M_print of print_destination * string (*Destination, message to print.*)
| M_flush of print_destination
Messages that can be received.
val set_max_message_size : int -> unit
Set the maximum size of packets.

If you know that your serialized values, exceptions and task names are never longer than n bytes, consider setting the maximum message size to n. Otherwise someone can send a ridiculous size, then the same ridiculous amount of data, and your process will buffer it all, possibly running out of memory.

By default the maximum size is max_int.


Non-Blocking Functions


val send : 'a Procord_connection.t -> message -> unit
Send a message.
val send_value : 'a Procord_connection.t -> string -> unit
Send a value (input or output).
val send_task_name : 'a Procord_connection.t -> string -> unit
Send the name of the task to execute.
val send_exception : 'a Procord_connection.t -> string -> unit
Send an exception message.
val send_unknown_exception : 'a Procord_connection.t -> string -> unit
Send an unknown exception message.
val send_error : 'a Procord_connection.t -> error -> unit
Send an error message.
val send_print : 'a Procord_connection.t ->
print_destination -> string -> unit
Send a message to be printed using Format.fprintf.

The worker can use this to make the main program call Format.fprintf. It is unspecified whether the main program can send messages like this to the worker.

val send_flush : 'a Procord_connection.t -> print_destination -> unit
Send a flush request.

The worker can use this to make the main program call Format.pp_print_flush. It is unspecified whether the main program can send messages like this to the worker.

val receive : 'a Procord_connection.t -> message
Try to receive a message from a connection.

May raise Error E_ill_formed_message.


Blocking Functions


val blocking_receive : 'a Procord_connection.t -> message
Receive a message.

May raise Error.

val blocking_receive_task_name : 'a Procord_connection.t -> string
Receive a task name.

May raise Error.

val blocking_receive_value : 'a Procord_connection.t -> string
Receive a serialized value.

May raise Error.


Formatters and Destinations


val register_destination : custom_destination -> Format.formatter -> unit
Register a formatter as a custom destination. If the worker sends to this destination, the main program will print on this formatter. To send to this destination, the worker can use Procord_worker.make_redirected_formatter.

Multiples destinations are not supported: only the last formatter receives the message.

This can be called before Procord_worker.run, although it only affects the main program. From the worker, you should use Procord_worker.redirect_formatter or Procord_worker.formatter_of_destination.

val formatter_of_destination : print_destination -> Format.formatter option
Return the formatter corresponding to a destination.

Return None if the destination custom and unregistered.


Protocol Description



A sequence of messages is sent on the connection. (See type message.) Nothing else can be sent, and M_none cannot really be sent either.

Each message is of the form:

SIZE KIND BODY

The SIZE is a sequence of ASCII digits ('0' to '9'). The KIND is a single character which is not a digit. The BODY is a string of SIZE bytes.

Each message has a specific KIND and a specific way to handle BODY:

Examples: