hiredis-client 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c30e3ee9498ead669c8f956cdd01a5f5c461af38a8eedaca5726622663d5284
|
4
|
+
data.tar.gz: '086288891e30a5b1966b60279af5eb7b3573a5cbb35ce64b974ca289a9eedbf1'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be4dd95865da29525ee3a6ce4b1cc8c7c3813e6589a3dc97a6270dc8bdbe99803cfe46c581ab4f255d2b9e8470e3dc9557d30061870c266197974703da5447f7
|
7
|
+
data.tar.gz: 17015559919a8008b8ad66cf743134f16cb91c19be7c97685faa0bb8a02b49dabdb66986eadc00269af61ace4e9ce62a0b336d0619d64fb56beccaa1364b75ff
|
@@ -311,14 +311,28 @@ static VALUE hiredis_alloc(VALUE klass) {
|
|
311
311
|
return TypedData_Make_Struct(klass, hiredis_connection_t, &hiredis_connection_data_type, connection);
|
312
312
|
}
|
313
313
|
|
314
|
+
void redis_set_io_error(redisContext *context, int err) {
|
315
|
+
if (err) {
|
316
|
+
errno = err;
|
317
|
+
}
|
318
|
+
context->err = REDIS_ERR_IO;
|
319
|
+
(void)!strerror_r(errno, context->errstr, sizeof(context->errstr));
|
320
|
+
}
|
321
|
+
|
314
322
|
static inline void redis_raise_error_and_disconnect(redisContext *context, VALUE timeout_error) {
|
315
323
|
if (!context) return;
|
316
324
|
|
317
325
|
int err = context->err;
|
318
326
|
char errstr[128];
|
319
|
-
|
327
|
+
if (context->err) {
|
328
|
+
strncpy(errstr, context->errstr, 128);
|
329
|
+
}
|
320
330
|
redisFree(context);
|
321
331
|
|
332
|
+
if (!err) {
|
333
|
+
rb_raise(timeout_error, "Unknown Error");
|
334
|
+
}
|
335
|
+
|
322
336
|
// OpenSSL bug: The SSL_ERROR_SYSCALL with errno value of 0 indicates unexpected EOF from the peer.
|
323
337
|
if (errno == EAGAIN || (err == REDIS_ERR_IO && errno == 0)) {
|
324
338
|
errno = 0;
|
@@ -431,26 +445,28 @@ static VALUE hiredis_connect_finish(hiredis_connection_t *connection, redisConte
|
|
431
445
|
|
432
446
|
int writable = 0;
|
433
447
|
int optval = 0;
|
448
|
+
errno = 0;
|
434
449
|
socklen_t optlen = sizeof(optval);
|
435
450
|
|
436
451
|
/* Wait for socket to become writable */
|
437
452
|
if (hiredis_wait_writable(context->fd, &connection->connect_timeout, &writable) < 0) {
|
453
|
+
redis_set_io_error(context, ETIMEDOUT);
|
438
454
|
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
439
455
|
}
|
440
456
|
|
441
457
|
if (!writable) {
|
442
|
-
|
458
|
+
redis_set_io_error(context, ETIMEDOUT);
|
443
459
|
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
444
460
|
}
|
445
461
|
|
446
462
|
/* Check for socket error */
|
447
463
|
if (getsockopt(context->fd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0) {
|
448
|
-
context
|
464
|
+
redis_set_io_error(context, 0);
|
449
465
|
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
450
466
|
}
|
451
467
|
|
452
468
|
if (optval) {
|
453
|
-
|
469
|
+
redis_set_io_error(context, optval);
|
454
470
|
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
455
471
|
}
|
456
472
|
|
@@ -602,14 +618,17 @@ static VALUE hiredis_flush(VALUE self) {
|
|
602
618
|
return Qtrue;
|
603
619
|
}
|
604
620
|
|
621
|
+
|
622
|
+
#define HIREDIS_FATAL_CONNECTION_ERROR -1
|
623
|
+
#define HIREDIS_CLIENT_TIMEOUT -2
|
624
|
+
|
605
625
|
static int hiredis_read_internal(hiredis_connection_t *connection, VALUE *reply) {
|
606
626
|
void *redis_reply = NULL;
|
607
627
|
int wdone = 0;
|
608
628
|
|
609
629
|
/* Try to read pending replies */
|
610
630
|
if (redisGetReplyFromReader(connection->context, &redis_reply) == REDIS_ERR) {
|
611
|
-
|
612
|
-
return -1;
|
631
|
+
return HIREDIS_FATAL_CONNECTION_ERROR; // Protocol error
|
613
632
|
}
|
614
633
|
|
615
634
|
if (redis_reply == NULL) {
|
@@ -618,20 +637,19 @@ static int hiredis_read_internal(hiredis_connection_t *connection, VALUE *reply)
|
|
618
637
|
errno = 0;
|
619
638
|
|
620
639
|
if (hiredis_buffer_write_nogvl(connection->context, &wdone) == REDIS_ERR) {
|
621
|
-
|
622
|
-
return -1;
|
640
|
+
return HIREDIS_FATAL_CONNECTION_ERROR; // Socket error
|
623
641
|
}
|
624
642
|
|
625
643
|
if (errno == EAGAIN) {
|
626
644
|
int writable = 0;
|
627
645
|
|
628
646
|
if (hiredis_wait_writable(connection->context->fd, &connection->write_timeout, &writable) < 0) {
|
629
|
-
return
|
647
|
+
return HIREDIS_CLIENT_TIMEOUT;
|
630
648
|
}
|
631
649
|
|
632
650
|
if (!writable) {
|
633
651
|
errno = EAGAIN;
|
634
|
-
return
|
652
|
+
return HIREDIS_CLIENT_TIMEOUT;
|
635
653
|
}
|
636
654
|
}
|
637
655
|
}
|
@@ -641,20 +659,19 @@ static int hiredis_read_internal(hiredis_connection_t *connection, VALUE *reply)
|
|
641
659
|
errno = 0;
|
642
660
|
|
643
661
|
if (hiredis_buffer_read_nogvl(connection->context) == REDIS_ERR) {
|
644
|
-
|
645
|
-
return -1;
|
662
|
+
return HIREDIS_FATAL_CONNECTION_ERROR; // Socket error
|
646
663
|
}
|
647
664
|
|
648
665
|
if (errno == EAGAIN) {
|
649
666
|
int readable = 0;
|
650
667
|
|
651
668
|
if (hiredis_wait_readable(connection->context->fd, &connection->read_timeout, &readable) < 0) {
|
652
|
-
return
|
669
|
+
return HIREDIS_CLIENT_TIMEOUT;
|
653
670
|
}
|
654
671
|
|
655
672
|
if (!readable) {
|
656
673
|
errno = EAGAIN;
|
657
|
-
return
|
674
|
+
return HIREDIS_CLIENT_TIMEOUT;
|
658
675
|
}
|
659
676
|
|
660
677
|
/* Retry */
|
@@ -662,8 +679,7 @@ static int hiredis_read_internal(hiredis_connection_t *connection, VALUE *reply)
|
|
662
679
|
}
|
663
680
|
|
664
681
|
if (redisGetReplyFromReader(connection->context, &redis_reply) == REDIS_ERR) {
|
665
|
-
|
666
|
-
return -1;
|
682
|
+
return HIREDIS_FATAL_CONNECTION_ERROR; // Protocol error
|
667
683
|
}
|
668
684
|
}
|
669
685
|
}
|
@@ -681,9 +697,19 @@ static VALUE hiredis_read(VALUE self) {
|
|
681
697
|
ENSURE_CONNECTED(connection);
|
682
698
|
|
683
699
|
VALUE reply = Qnil;
|
684
|
-
|
685
|
-
|
700
|
+
switch (hiredis_read_internal(connection, &reply)) {
|
701
|
+
case HIREDIS_FATAL_CONNECTION_ERROR:
|
702
|
+
// The error is unrecoverable, we eagerly close the connection to ensure
|
703
|
+
// it won't be re-used.
|
704
|
+
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientReadTimeoutError);
|
705
|
+
break;
|
706
|
+
case HIREDIS_CLIENT_TIMEOUT:
|
707
|
+
// The timeout might have been expected (e.g. `PubSub#next_event`).
|
708
|
+
// we let the caller decide if the connection should be closed.
|
709
|
+
rb_raise(rb_eRedisClientReadTimeoutError, "Unknown Error");
|
710
|
+
break;
|
686
711
|
}
|
712
|
+
|
687
713
|
if (reply == Redis_Qfalse) {
|
688
714
|
// See reply_create_bool
|
689
715
|
reply = Qfalse;
|
@@ -935,8 +935,9 @@ int redisBufferRead(redisContext *c) {
|
|
935
935
|
int nread;
|
936
936
|
|
937
937
|
/* Return early when the context has seen an error. */
|
938
|
-
if (c->err)
|
938
|
+
if (c->err) {
|
939
939
|
return REDIS_ERR;
|
940
|
+
}
|
940
941
|
|
941
942
|
nread = c->funcs->read(c, buf, sizeof(buf));
|
942
943
|
if (nread > 0) {
|
@@ -41,7 +41,12 @@ class RedisClient
|
|
41
41
|
raise CannotConnectError, error.message, error.backtrace
|
42
42
|
end
|
43
43
|
else
|
44
|
-
|
44
|
+
begin
|
45
|
+
connect_tcp(config.host, config.port)
|
46
|
+
rescue SystemCallError => error
|
47
|
+
error_code = error.class.name.split("::").last
|
48
|
+
raise CannotConnectError, "Failed to connect to #{config.host}:#{config.port} (#{error_code})"
|
49
|
+
end
|
45
50
|
end
|
46
51
|
|
47
52
|
if config.ssl
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hiredis-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.11.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.11.0
|
27
27
|
description:
|
28
28
|
email:
|
29
29
|
- jean.boussier@gmail.com
|