# Why does write-bytes-avail-evt not return an error?

**URL:** https://racket.discourse.group/t/why-does-write-bytes-avail-evt-not-return-an-error/2230
**Category:** Questions & Answers
**Tags:** question
**Created:** [August 20, 2023, 3:11am UTC](https://racket.discourse.group/t/why-does-write-bytes-avail-evt-not-return-an-error/2230 "2023-08-20T03:11:19Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![janus](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/janus/32/1115_2.png) [@janus](https://racket.discourse.group/u/janus)
#### Post date: [August 20, 2023, 3:11am UTC](https://racket.discourse.group/t/why-does-write-bytes-avail-evt-not-return-an-error/2230/1 "2023-08-20T03:11:19Z")

</div>

I am trying to find how how I can handle all the errors that can happen related to a TCP connection.

So I have written this server:

```scheme
#lang racket/base
(require racket/tcp)
(define listener (tcp-listen 8000))
(define o (let-values ([(in out) (tcp-accept listener)]) out))
(displayln "Sleeping")
(sleep 1)
(displayln "Writing")
(define evt (write-bytes-avail-evt #"apple" o))
(define res (sync evt))
(displayln res)
(displayln "Flushing")
(flush-output o)

```

And I connect to it with this client (Python, sorry):

```python
import struct, socket
s = socket.socket(socket.AF_INET6)
s.connect(("::1", 8000))
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
s.close() # provokes Connection Reset at host

```

Now, I would expect a failure to occur during sync'ing on the event, since [the documentation for write-bytes-avail-evt](https://docs.racket-lang.org/reference/Byte_and_String_Output.html#%28def._%28%28quote._~23~25kernel%29._write-bytes-avail-evt%29%29) says that

> the event becomes ready when bytes are written (unbuffered) to the port.

But it seems like the error is only occurring during flushing, which I don't understand, since the writing was supposed to be 'unbuffered'. Isn't the flushing about writing the buffer? Is it another buffer? How do I turn it off?

Here is the output I get:

```plaintext
Sleeping
Writing
5
Flushing
error writing to stream port
  system error: Connection reset by peer; errno=104
  context...:
   body of "/home/janus/racket-tcp/serv.rkt"

```

---

<div class="post-metadata">

### Author: ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)
#### Post date: [August 20, 2023, 1:10pm UTC](https://racket.discourse.group/t/why-does-write-bytes-avail-evt-not-return-an-error/2230/2 "2023-08-20T13:10:08Z")

</div>

Hej Janus,

As I read the output, this

```scheme
...
(define evt (write-bytes-avail-evt #"apple" o))
(define res (sync evt))
(displayln res)

```

writes the 5 bytes #"apple" to the buffer of output port `o` succesfully.

Then the Python client closes the connection.

Then `(flush-output o)` attempts to flush a buffer - but since the port is closed, an error is signaled.

Using `(file-stream-buffer-mode o)` you can see that the default buffer of `o` is `block`.  
Setting the buffer mode to `'none` with `(file-stream-buffer-mode o 'none)` changes the  
location of the error to what you expected:

```scheme
Sleeping
Writing
error writing to stream port
  system error: Broken pipe; errno=32
  context...:
   body of "/Users/soegaard/tmp/racket-server.rkt"

```

---

<div class="post-metadata">

### Author: ![janus](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/janus/32/1115_2.png) [@janus](https://racket.discourse.group/u/janus)
#### Post date: [August 20, 2023, 5:39pm UTC](https://racket.discourse.group/t/why-does-write-bytes-avail-evt-not-return-an-error/2230/3 "2023-08-20T17:39:34Z")

</div>

Hej Jens Axel,

> [@soegaard](#):
>
> writes the 5 bytes #"apple" to the buffer of output port `o` succesfully.
> 
> Then the Python client closes the connection.

I don't understand how this is the ordering of events, since as the Python is written, the closing happens just after the connection is established. That is, immediately after the `tcp-accept`.

This is why I put the `sleep` there — I wanted to make sure the connection is already closed by the time the bytes are written.

> `(file-stream-buffer-mode o 'none)`

This seems to be what I want. Thank you.

> [@janus](#):
>
> the event becomes ready when bytes are written (unbuffered) to the port.

I suppose the correct parsing of this statement is that:

- When unbuffered, the event becomes written when the bytes are written to the port.

That way, no assertion is made about what happens if the port is buffered. That would make it consistent with the behaviour that we're seeing. However, I do think it's a curious application of parenthesis.

---

<div class="post-metadata">

### Author: ![mflatt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mflatt/32/6_2.png) [@mflatt](https://racket.discourse.group/u/mflatt)
#### Post date: [August 22, 2023, 4:36pm UTC](https://racket.discourse.group/t/why-does-write-bytes-avail-evt-not-return-an-error/2230/4 "2023-08-22T16:36:50Z")

</div>

I think this is a bug in `write-bytes-avail-evt` for Racket CS.

As @janus quotes from the documentation, the event should become ready only when bytes are written, as opposed to being buffered. The port's buffer mode is not supposed to matter. Along those lines, Racket BC behaves as expected without `(file-stream-buffer-mode o 'none)`.

The bug appears to be simply a wrong flag passed to the port's underlying output function where a flag to disable buffering was intended. I'll push a repair. Meanwhile, `(file-stream-buffer-mode o 'none)` is a good workaround.
