On Saturday, December 21, 2019 at 11:33:15 AM UTC-8, Ian Lance Taylor wrote:
>
> On Sat, Dec 21, 2019 at 7:09 AM Daniel Eloff <dan....@gmail.com 
> <javascript:>> wrote: 
> > 
> > Digging a little, it seems Go net poller uses edge triggered epoll on 
> Linux. One of the harder considerations about using edge-triggered epoll is 
> you have to read()/write() until EGAIN, otherwise you will not receive 
> another read/write event for the socket when you call epoll_wait. 
> > 
> > My question is, how does this work if you use the new(ish) RawConn 
> interface? It's not stated that there are any requirements to read/write 
> until EGAIN, just that it's expected that the programmer calls read/write 
> (presumably through syscall.Read/Write.) What happens if you return e.g. 
> done=true without calling read/write at all? This may be useful if you just 
> want to wait until data is available for reading without tying up a buffer 
> in a read call, e.g. if you have a long-lived but idle connection like a 
> websocket, or you're waiting for follow-up requests on an http keep-alive 
> connection, or http2 connection as in grpc. 
> > 
> > I went through the poller code, but did not manage to figure out the 
> answer. 
>
> As far as I can see there is no problem if the function returns true 
> without doing a read.  In the normal file I/O case, a Read will never 
> wait for the poller unless the system call returns EAGAIN.  That is, a 
> call to the Read method does not start by waiting for the poller to 
> report that the descriptor is ready.  It always calls the read system 
> call, and only if read returns EAGAIN does it wait for the poller.
>

I think that's the missing piece for me to understand what the poller is 
doing here.
 

>
> However, I think there might be a potential problem if the RawConn 
> Read method is called with a function that returns false after making 
> a read call that does not return EAGAIN.  In that case the net package 
> will wait for the poller, but there might be nothing that triggers it. 
>

Yes, I think that should be added to the docs.
 

>
> Come to think of it, you said return done=true but you probably meant 
> return done=false.  You're right: I don't think that will work.  I 
> think that as the docs say "f is expected to try to read from the file 
> descriptor." 
>

Yeah you're right, I meant return done=false without calling read. This 
will cause the goroutine to be suspended until more data comes in for the 
fd. But, if there was data waiting already then I agree this code is broken 
in my new understanding, as the edge triggered event will not fire for it. 
So really one can only ever return done=false if you read until EAGAIN, 
which should be clarified in the docs. I could switch the fd to 
level-triggered, which is not portable and could interact badly with the 
netpoller, so I think that's a bad idea. Better would be call read with a 
small stack buffer, and if it succeeds, allocate a real buffer and copy the 
data to there and read until EAGAIN or sufficient data has been read. That 
doesn't cost anything more (either way it's still one syscall.)

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/14c9d21b-b81e-4fa7-aabb-b91ec9b351ae%40googlegroups.com.

Reply via email to