Reputation: 2731
I am currently doing the Ruby on the Web project for The Odin Project. The goal is to implement a very basic webserver that parses and responds to GET
or POST
requests.
My solution uses IO#gets
and IO#read(maxlen)
together with the Content-Length Header attribute to do the parsing.
Other solution use IO#read_nonblock
. I googled for it, but was quite confused with the documentation for it. It's often mentioned together with Kernel#select
, which didn't really help either.
Can someone explain to me what the nonblock calls do differently than the normal ones, how they avoid blocking the thread of execution, and how they play together with the Kernel#select
method?
Upvotes: 1
Views: 81
Reputation: 2020
In a blocking write you wait until bytes got written to a file, on the other hand a nonblocking write exits immediately. It means, that you can continue to execute your program, while operating system asynchronously writes data to a file. Then, when you want to write again, you use select to see whether the file is ready to accept next write.
Upvotes: 1
Reputation: 19375
explain to me what the nonblock calls do differently than the normal ones
The crucial difference in behavior is when there is no data available to read at call time, but not at EOF:
read_nonblock()
raises an exception kind of IO::WaitReadableread(length)
waits until length bytes are read (or EOF)how they avoid blocking the thread of execution
According to the documentation, #read_nonblock is using the read(2) system call after O_NONBLOCK is set for the underlying file descriptor.
how they play together with the Kernel#select method?
There's also IO.select
. We can use it in this case to wait for availability of input data, so that a subsequent read_nonblock()
won't cause an error. This is especially useful if there are multiple input streams, where it is not known from which stream data will arrive next and for which read()
would have to be called.
Upvotes: 1