Ocamlnet 3 Reference Manual : Netchannels.rec_out_channel

# Class type Netchannels.rec_out_channel

    class type rec_out_channel = object .. end

Recommended output class type for library interoperability.

## Description

This class type is defined in "Basic I/O class types" as collaborative effort of several library creators.

    method output : string -> int -> int -> int

Takes octets from the string and writes them into the channel. The first `int` argument is the position of the substring, and the second `int` argument is the length of the substring where the data can be found. The method returns the number of octets actually written.

The implementation may choose to collect written octets in a buffer before they actually delivered to the underlying resource.

When the channel is non-blocking, and there are currently no bytes to write, the number 0 will be returned. This has been changed in ocamlnet-0.97! In previous releases this behaviour was undefined.

When the channel is closed, the exception `Closed_channel` will be raised if an ocamlnet implementation is used. For implementations of other libraries there is no standard for this case.

    method flush : unit -> unit

If there is a write buffer, it will be flushed. Otherwise, nothing happens.

    method close_out : unit -> unit

Flushes the buffer, if any, and closes the channel for output.

When the channel is already closed, this is a no-op.

## How to close channels in case of errors

The `close_out` method has actually two tasks: First, it writes out all remaining data (like `flush`), and second, it releases OS resources (e.g. closes file descriptors). There is the question what has to happen when the write part fails - is the resource released anyway or not?

We choose here a pragmatic approach under the assumption that an OS error at close time is usually unrecoverable, and it is more important to release the OS resource. Also, we assume that the user is wise enough to call `flush` first if it is essential to know write errors at close time. Under these assumptions:

- The `flush` method fully reports any errors when writing out the remaining data.
- When `flush` raises an error exception, it should discard any data in the buffer. This is not obligatory, however, but considered good practice, and is subject to discussion.
- The `close_out` method usually does not report errors by raising exceptions, but only by logging them via `Netlog`. The OS resource is released in any case. As before, this behavior is not obligatory, but considered as good practice, and subject to discussion.

This ensures that the following code snippet reports all errors, but also releases OS resources:

           try
             ch # flush();
             ch # close_out();
           with error ->
              ch # close_out(); raise error

There are some cases where data can be first written when it is known that the channel is closed. These data would not be written by a preceding `flush`. In such cases:

- The best way to deal with it is to define another method, e.g. called `write_eof`, that marks the data as logically being complete, so a following `flush` can do the complete shutdown cycle of the channel.
- At least, however, one should allow then that a double `close_out` releases the descriptor: the first `close_out` will report the error condition as exception, but discard all data in the channel. The second `close_out` finally releases the OS resource.

In any way, hard errors indicating bugs of the program logic (like invalid file descriptors) should always be immediately reported.