答复: 答复: (fc) FileChannel.transferFrom/transferFromArbitraryChannel to return -1 at some error condition
lihuaming (A)
lihuaming3 at huawei.com
Sat Jan 30 07:52:59 UTC 2021
Hi Alan,
Please check my comments below, I mark them with starting ###. (sorry to use the Outlook again, some emails were lost in thunderbird, don’t know why.)
发件人: Alan Bateman [mailto:Alan.Bateman at oracle.com]
发送时间: 2021年1月30日 1:07
收件人: lihuaming (A) <lihuaming3 at huawei.com>; nio-dev at openjdk.java.net
主题: Re: 答复: (fc) FileChannel.transferFrom/transferFromArbitraryChannel to return -1 at some error condition
On 29/01/2021 12:51, lihuaming (A) wrote:
Here is a simple demo, I don't use FileChannel.transferFrom directly, but I hope I can clarify the situation.
When ServerHangHttp and Client are up for a while (please check the bottom), no matter Server close the socket explicitly or kill by "kill -9 xxx", the client side will print out "[client] read : -1" continuously. so, if we are using FileChannel.transferFrom which will call transferFromArbitraryChannel which will call ReadableByteChannel.read, ReadableByteChannel.read will return -1, but transferFromArbitraryChannel will return 0, so as FileChannel.transferFrom. Based on this return value, following while loop will be a infinite loop, and user don't want to call something like "call sth like srcSocketChannel.read(...)", please check the reason in comments below.
while (srcSocketChannel.isOpen()) {
long l = fileChannel.transferFrom(srcSocketChannel,...);
// user could call sth like srcSocketChannel.read(...), and expect it return -1, and break the loop, but it will be unacceptable for some program, where they would like to very quick copy, so called "zero" copy through fileChannel.transferFrom, and they don't want to add an extra check like "srcSocketChannel.read(...)"
if (l == -1) { // break out the while loop }
}
At this situation, I think it's more friendly to have fileChannel.transferFrom returns -1.
The Client in the reproducer has a bug in that it will call read with 0 remaining bytes once it has read 100 bytes in total. So I would expect it will eventually spin reading 0 rather than -1.
### Sorry, please ignore this bug, I do kill the server manually shortly after it’s connected with client.
If the server does terminate and close the connection gracefully then the client will spin reading -1 but only if reads -1/EOF before 1000 bytes are read.
### Yes, as I kill the server manually, so client read will return -1.
For transferFrom reading from an arbitrary channel then it may read bytes before EOF, in which case it will write those bytes to the file and return the number of bytes written/transferred. If called again then it will read again and just 0 because there are no bytes transferred. I don't see how we can could change this API without breaking existing usages that keeping a running code.
### if the arbitrary channel was just closed by peer side, transferFrom will return 0 this time or next time, and there is no way for it knows that the underlying socket was closed, unless it calls channel.read. But for performance consideration, I think some framework/program would like to call FileChannel,transferFrom(channel, …) only, rather than followed by a read+write just in case of channel is closed by peer side; read+write can be optimized by only do it if transferFrom(channel, …) returns 0, but it still has some extra cost, and code is not simple and straight.
### I don’t think this is jdk bug and I do have concern about the compatibility too and explained to framework/program developers, but I can also understand their points, so want to see if there are some way to make it more friendly to framework/program developers in this situation. Hope I have made it clear ☺. If there is no other better solutions, I will let them know that it’s better to modify their code.
Thanks Alan for discussion.
Hamlin
-Alan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/nio-dev/attachments/20210130/c8e51728/attachment-0001.htm>
More information about the nio-dev
mailing list