• fileevent writable

    From pd@21:1/5 to All on Sun Feb 19 11:23:58 2023
    It's not clear to me the concept of writable channel, documentation [1] says:

    "A channel is considered to be writable if at least one byte of data can be written to the underlying file or device without blocking, or if an error condition is present on the underlying file or device."

    But for my understanding a channel is always writable since you can always write to it, thinking in a file you can always add a line or byte, the same for a socket. Sure the key is without blocking but if you configure the channel to nonblocking then
    you always write to it without blocking.

    One example I've found using 'writable' is [2] and I think the use there is to detect when a socket is ready to send bytes to it, for example when it's fully opened

    But cannot find much mores examples, specially file event examples.

    May you clarify the concept with an example or send me to some clear documentation?

    Thanks in advance

    [1] https://www.tcl-lang.org/man/tcl/TclCmd/fileevent.htm
    [2] https://wiki.tcl-lang.org/page/Port+scanning+in+tcl

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to [email protected] on Sun Feb 19 21:53:15 2023
    pd <[email protected]> wrote:
    But for my understanding a channel is always writable since you can
    always write to it, thinking in a file you can always add a line or
    byte, the same for a socket.

    It is not correct to think a file can always be written into. Consider
    a pipe between two processes (which is implemented as stdout of the
    writer being the same file as stdin of the reader process).

    A typical pipe buffer size is 4kib (4096 bytes).

    If the reader consumes bytes at the rate of 1 byte per second, but the
    writer writes bytes at the rate of 2 bytes per second, eventually the
    4kib buffer will fill.

    Once it is filled, the writer will only be able to write at the rate of
    1 byte per second (same as the read rate of the reader).

    What will happen at the "file interface" level for the writer is that 2
    bytes before the buffer fills, a two byte write will complete
    immediately. But once the buffer is full, a two byte write by the
    writer will take two seconds to complete, and the writer will block in
    the write() call for two seconds while the reader consumes two bytes.

    Sure the key is without blocking but if you configure the channel to nonblocking then you always write to it without blocking.

    Tcl's 'nonblocking' is an abstraction [1] where Tcl hides the underlying
    stdio interface from you and allows you to pretend to write as much as
    you like. Reality is the Tcl runtime is buffering your writes up in
    memory for you beind the scenes.

    One example I've found using 'writable' is [2] and I think the use
    there is to detect when a socket is ready to send bytes to it, for
    example when it's fully opened

    Sockets can also block for the same reason as the pipe, the reader is
    on a network that transmits 100 bytes per second, while the writer is
    on a network that transmits 1000 bytes per second. If the writer
    writes bytes at full speed, eventually it has to block to not overrun
    the writer.

    Note also, that even a disk file can block. If the disk is connected
    via an interface capable of writing 1Mbyte/s, but the attached computer
    CPU can write to the interface at 10Mbyte/s, eventually the CPU has to
    be "blocked" from writing more data because the reader (the disk) can
    not keep up.

    [1] The C stdio interface provides "non-blocking" I/O by returning a
    "status message" from the write() call that indicates: "blocked, try again later" and it is up to the programmer to write the appropriate retry
    loop. Tcl hides that 'retry' complexity inside the runtime and exposes
    its "files can always be written" abstraction to the script level.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Mon Feb 20 11:43:31 2023
    Am 19.02.2023 um 20:23 schrieb pd:
    It's not clear to me the concept of writable channel, documentation [1] says:

    "A channel is considered to be writable if at least one byte of data can be written to the underlying file or device without blocking, or if an error condition is present on the underlying file or device."

    But for my understanding a channel is always writable since you can always write to it, thinking in a file you can always add a line or byte, the same for a socket. Sure the key is without blocking but if you configure the channel to nonblocking then
    you always write to it without blocking.

    One example I've found using 'writable' is [2] and I think the use there is to detect when a socket is ready to send bytes to it, for example when it's fully opened

    But cannot find much mores examples, specially file event examples.

    May you clarify the concept with an example or send me to some clear documentation?

    Thanks in advance

    [1] https://www.tcl-lang.org/man/tcl/TclCmd/fileevent.htm
    [2] https://wiki.tcl-lang.org/page/Port+scanning+in+tcl

    Hi PD,

    thanks for the question.

    A very common usage of writable events is an asynchoneous client socket connection.
    While the socket connects, it is not writable.

    The result of the connect process may be a writable socket or an error.
    Due to that, an asyncroneous socket often uses the following programming scheme:

    - connect asynchroneously: socket -async
    - instal writable event
    - in the writable event, do the following:
    - check for error (fconfigure -error)
    - install a readable event
    - eventually send initial data
    - remove the writable event. It has no use any more, as the socket is
    now always writable.

    An example is the http core package.

    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)