popen: accept a negative timeout and interpret it as zero
Sometimes it is convenient to perform a substraction like deadline - now() and pass the resulting value as a timeout. I would expect the following semantic: if timeout <= 0 then perform an action if it is ready-to-go (would not trigger EWOULDBLOCK and fiber yield). Otherwise, return a timeout error.
popen now interprets any negative timeout value as an error.
https://github.com/tarantool/tarantool/blob/927e351625292c20ff6d07cc70164725fce8b338/src/lua/popen.c#L285-L297
https://github.com/tarantool/tarantool/blob/927e351625292c20ff6d07cc70164725fce8b338/src/lua/popen.c#L1743-L1745
The list of affected methods:
ph:wait({timeout = -1})
ph:read({timeout = -1})
ph:write({timeout = -1})
It is definitely not a bug, rather a feature request (semantic change even).
We also didn't come to a resolution how it should behave in this case - it's not clear should a popen call fails with a timeout if it takes longer than proposed timeout to execute. Say, popen.new('...', {timeout=0})
See also https://github.com/tarantool/tarantool/issues/7970
@olegrok Thanks for pointing it out!
@sergos OK, let's call it a feature. I don't care much in this case.
popen.new() has no timeout and it possibly shouldn't. I want to clarify that we're talking about calls that wait for some externally produced event: for example, arriving data from another process.
Let's take :read() as an example.
If the call has zero timeout (or a negative timeout), it should return immediately, where it means don't wait for an external event. It is OK to do some (relatively) fast local work like a buffer copying.
Let's assume the data is already there and the call can return immediately with the new data or report a timeout error. In this case, it should return the data.
In other works, zero/negative timeout means "don't wait for data arriving" in this case.
Similarly, it means "don't wait for a free space in the pipe buffer" for :write().
And, finally, it means "don't wait for the process termination" for :wait() (buf it is OK to send a zero signal and look on its result).