hiredis icon indicating copy to clipboard operation
hiredis copied to clipboard

redisBufferWrite() failures on send() "continue" case - new with 1.0.0

Open astruble58 opened this issue 2 years ago • 1 comments

Converting from 0.13.3 to 1.0.0, we had one usage that consistently failed, keeping the application from starting. We ended up patching redisNetWrite() to match the behavior of v0.13.3:

@@ -83,7 +83,7 @@ ssize_t redisNetWrite(redisContext *c) {
     ssize_t nwritten = send(c->fd, c->obuf, sdslen(c->obuf), 0);
     if (nwritten < 0) {
         if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR
)) {
-            /* Try again later */
+            return 0 ; /* Try again later - PATCH to match 0.13.3 */
         } else {
             __redisSetError(c, REDIS_ERR_IO, NULL);
             return -1;

The problem with 1.0.0 is that the "Try again later" branch passes the negative return back to redisBufferWrite(), which will declare that as a permanent connection failure. In 0.13.3, there is no redisNetWrite() and the "Try again later" logic is embedded in redisBufferWrite():

839           nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
840           if (nwritten == -1) {
841               if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == !
      EINTR)) {
842                   /* Try again later */
843               } else {
844                   __redisSetError(c,REDIS_ERR_IO,NULL);
845                   return REDIS_ERR;
846               }
847           } else if (nwritten > 0) {

So the additional layering of v1.0.0 didn't get the interface behavior quite right.

astruble58 avatar Aug 19 '21 15:08 astruble58

This will be fixed by #961.

y-yagi avatar Nov 07 '21 02:11 y-yagi

Closing via #1106

michael-grunder avatar Sep 06 '22 03:09 michael-grunder