Improve wait callback and timeout handling #110
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This makes a couple improvements to how we wait for the socket to become ready for I/O.
First this refactors
TRILOGY_RB_TIMEOUT
to a "real" error status in the C library (though currently nothing in the C library raises it), which allows it to be negative like all the other errors (and avoids being confused with a successful read/write of size 1).Next this makes
_cb_ruby_wait
return this new status code instead of SYSERR when there is a timeout, allowing it to propogate throughtrilogy_sock_upgrade_ssl
and similar correctly. This allows differentiating between actually syserrors which set errno and timeouts. Also this can show the difference betweenrb_wait_for_single_fd
returning-1
(a syscall error, which I think in practice will be extremely rare) and 0 (a timeout).Finally the last two commits ensure that the socket is shut down on either a socket timeout we see, or from an external exception (like
Timeout.timeout
). For the latter we must wrap the waiting in anrb_protect
, which previously we were doing correctly for queries, but not for other operations (ex.ping
,change_db
). We have to shut down the socket because we've interrupted normal control flow and are likely either in the middle of a write (we've partly written our packet) or a read (there will be data sent from the server that we need to handle) so any further operations are invalid.