On 2/15/23 16:44, Ben Engbers wrote:
Hi
Op 15-02-2023 om 14:38 schreef Tomas Kalibera:
On 2/15/23 01:24, Ben Engbers wrote:
Hi,
December 27, 2021 I started a thread asking for help troubleshooting
non-blocking sockets.
..
I have two questions.
The first is where I can find R documentation on proper use of
non-blocking sockets and on the proper use of the socketSelect
function?
In addition to the demos I sent to you in that 2021 thread on
R-pkg-devel, you could also have a look at how it is used in R
itself, in the parallel package, in snowSOCK.R, to set up the snow
cluster in parallel. Some hints may be also found in the blog post
https://blog.r-project.org/2020/03/17/socket-connections-update/.
But, in principle, R API is just a thin layer on top of what the OS
provides, so general literature and tutorials on sockets should help,
there should be even textbooks used at CS universities in networking
classes.
Thanks for the suggestions!
Basically select() can tell you when data is ready (on input), when
the socket interface is able to accept more data (on output) or when
there is an incoming connection. In practice, you should not need any
delays to be inserted in your program to make it work - if that is
needed, it means that is an error in it (a race condition). If the
program is polling (checking in a loop whether something has already
happened, and then sleeping for a short while), the duration of the
sleep may indeed influence latency, but should not affect correctness
- if it does, there is an error.
In RBaseX I first calculate an MD5 hash that is send to the server and
then I check the status byte that is returned by the server.
writeBin(auth, private$conn)
socketSelect(list(conn))
Accepted <- readBin(conn, what = "raw", n = 1) == 0
Without the second line, 'Accepted' is always FALSE. With this line it
is TRUE.
BaseX provides example API's in several languages. I've looked at
several but indeed none uses any form of delay.
All API's follow the same pattern, calculate a MD5, send it to the
server and check the status byte. So the server is not likely to
enforce a delay. So there is nothing left but to look for that racing
condition ;-(
Without knowing more details, this looks ok. If you have a non-blocking
connection, and the server produces a response based on the client
request, the client has to take into account that it takes the server
some time to produce the response. Right, the sockets are full duplex
and so could be the communication protocol, but in this case it
apparently isn't, it is request/response.
Without the second line, there would be a race condition between the
server sending a response and the client receiving it. With the second
line, the client waits for the server before it starts receiving. In
theory, one could be waiting for the response actively in a loop
(polling), but socketSelect() is better. Both ways would resolve the
race condition. Adding a single fixed-time wait, instead, would not
remove the race condition, because one can never be sure that the server
wouldn't take longer (apart from waiting too long most of the time).
In the example you are waiting only for a single byte. But if the
response may be longer, one needs to take into account in the client
that not all bytes of the response may be available right away. One
would keep receiving the data in a loop, as they become available (e.g.
socketSelect() would tell), keep appending them to a buffer, and keep
looking for when they are complete.
Tomas
Ben
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel