hiredis-client 0.4.0 → 0.6.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 +4 -4
- data/ext/redis_client/hiredis/hiredis_connection.c +67 -22
- data/lib/redis_client/hiredis_connection.rb +5 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba60e75acf78441a3ee79cc33c7dd02be25481a229e6c3a697f6595864da50f5
|
4
|
+
data.tar.gz: 8e850b60219abce73e320a42b610fadfec522ab0f926c429a98f6c51dcfd862f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86f117da17118c442f127d11eec64d9dea91fb3da1070a111e2be1611815056e4443bcc2904d8e709bd3a4095e1704f9c32a47fb6a09688670c9f4d9221f4635
|
7
|
+
data.tar.gz: fa1896db0cf13d0d33ad812659f381968de920e1516fc05aa1467e1c302fd958b3fbfa9919171f6bdaff63a44e8d21c13de9fb8efd1b56524d6f84d1961d865a
|
@@ -31,6 +31,7 @@
|
|
31
31
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
32
32
|
|
33
33
|
#include "ruby.h"
|
34
|
+
#include "ruby/thread.h"
|
34
35
|
#include "ruby/encoding.h"
|
35
36
|
#include <errno.h>
|
36
37
|
#include <sys/socket.h>
|
@@ -45,8 +46,8 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
45
46
|
}
|
46
47
|
#endif
|
47
48
|
|
48
|
-
static VALUE
|
49
|
-
static VALUE
|
49
|
+
static VALUE rb_eRedisClientCommandError, rb_eRedisClientConnectionError, rb_eRedisClientCannotConnectError, rb_eRedisClientProtocolError;
|
50
|
+
static VALUE rb_eRedisClientReadTimeoutError, rb_eRedisClientWriteTimeoutError;
|
50
51
|
static ID id_parse, id_add, id_new;
|
51
52
|
|
52
53
|
typedef struct {
|
@@ -150,6 +151,12 @@ static void *reply_append(const redisReadTask *task, VALUE value) {
|
|
150
151
|
}
|
151
152
|
|
152
153
|
static void *reply_create_string(const redisReadTask *task, char *cstr, size_t len) {
|
154
|
+
if (len >= 4 && task->type == REDIS_REPLY_VERB) {
|
155
|
+
// Skip 4 bytes of verbatim type header.
|
156
|
+
cstr += 4;
|
157
|
+
len -= 4;
|
158
|
+
}
|
159
|
+
|
153
160
|
VALUE string = rb_external_str_new(cstr, len);
|
154
161
|
if (rb_enc_str_coderange(string) == ENC_CODERANGE_BROKEN) {
|
155
162
|
rb_enc_associate(string, rb_ascii8bit_encoding());
|
@@ -170,14 +177,12 @@ static void *reply_create_array(const redisReadTask *task, size_t elements) {
|
|
170
177
|
switch (task->type) {
|
171
178
|
case REDIS_REPLY_PUSH:
|
172
179
|
case REDIS_REPLY_ARRAY:
|
180
|
+
case REDIS_REPLY_SET:
|
173
181
|
value = rb_ary_new_capa(elements);
|
174
182
|
break;
|
175
183
|
case REDIS_REPLY_MAP:
|
176
184
|
value = rb_hash_new_capa(elements / 2);
|
177
185
|
break;
|
178
|
-
case REDIS_REPLY_SET:
|
179
|
-
value = rb_funcallv(rb_cSet, id_new, 0, NULL);
|
180
|
-
break;
|
181
186
|
default:
|
182
187
|
rb_bug("[hiredis] Unexpected create array type %d", task->parent->type);
|
183
188
|
break;
|
@@ -325,6 +330,8 @@ static inline void redis_raise_error_and_disconnect(redisContext *context, VALUE
|
|
325
330
|
case REDIS_ERR_IO:
|
326
331
|
rb_sys_fail(0);
|
327
332
|
break;
|
333
|
+
case REDIS_ERR_PROTOCOL:
|
334
|
+
rb_raise(rb_eRedisClientProtocolError, "%s", errstr);
|
328
335
|
default:
|
329
336
|
/* Raise something else */
|
330
337
|
rb_raise(rb_eRedisClientConnectionError, "%s", errstr);
|
@@ -420,7 +427,7 @@ static int hiredis_wait_writable(int fd, const struct timeval *timeout, int *iss
|
|
420
427
|
|
421
428
|
static VALUE hiredis_connect_finish(hiredis_connection_t *connection, redisContext *context) {
|
422
429
|
if (context->err) {
|
423
|
-
redis_raise_error_and_disconnect(context,
|
430
|
+
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
424
431
|
}
|
425
432
|
|
426
433
|
int writable = 0;
|
@@ -429,23 +436,23 @@ static VALUE hiredis_connect_finish(hiredis_connection_t *connection, redisConte
|
|
429
436
|
|
430
437
|
/* Wait for socket to become writable */
|
431
438
|
if (hiredis_wait_writable(context->fd, &connection->connect_timeout, &writable) < 0) {
|
432
|
-
redis_raise_error_and_disconnect(context,
|
439
|
+
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
433
440
|
}
|
434
441
|
|
435
442
|
if (!writable) {
|
436
443
|
errno = ETIMEDOUT;
|
437
|
-
redis_raise_error_and_disconnect(context,
|
444
|
+
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
438
445
|
}
|
439
446
|
|
440
447
|
/* Check for socket error */
|
441
448
|
if (getsockopt(context->fd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0) {
|
442
449
|
context->err = REDIS_ERR_IO;
|
443
|
-
redis_raise_error_and_disconnect(context,
|
450
|
+
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
444
451
|
}
|
445
452
|
|
446
453
|
if (optval) {
|
447
454
|
errno = optval;
|
448
|
-
redis_raise_error_and_disconnect(context,
|
455
|
+
redis_raise_error_and_disconnect(context, rb_eRedisClientCannotConnectError);
|
449
456
|
}
|
450
457
|
|
451
458
|
context->reader->fn = &reply_functions;
|
@@ -477,7 +484,7 @@ static VALUE hiredis_init_ssl(VALUE self, VALUE ssl_param) {
|
|
477
484
|
SSL_CONTEXT(ssl_param, ssl_context)
|
478
485
|
|
479
486
|
if (redisInitiateSSLWithContext(connection->context, ssl_context->context) != REDIS_OK) {
|
480
|
-
hiredis_raise_error_and_disconnect(connection,
|
487
|
+
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientCannotConnectError);
|
481
488
|
}
|
482
489
|
|
483
490
|
redisSSL *redis_ssl = redisGetSSLSocket(connection->context);
|
@@ -485,15 +492,15 @@ static VALUE hiredis_init_ssl(VALUE self, VALUE ssl_param) {
|
|
485
492
|
if (redis_ssl->wantRead) {
|
486
493
|
int readable = 0;
|
487
494
|
if (hiredis_wait_readable(connection->context->fd, &connection->connect_timeout, &readable) < 0) {
|
488
|
-
hiredis_raise_error_and_disconnect(connection,
|
495
|
+
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientCannotConnectError);
|
489
496
|
}
|
490
497
|
if (!readable) {
|
491
498
|
errno = EAGAIN;
|
492
|
-
hiredis_raise_error_and_disconnect(connection,
|
499
|
+
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientCannotConnectError);
|
493
500
|
}
|
494
501
|
|
495
502
|
if (redisInitiateSSLContinue(connection->context) != REDIS_OK) {
|
496
|
-
hiredis_raise_error_and_disconnect(connection,
|
503
|
+
hiredis_raise_error_and_disconnect(connection, rb_eRedisClientCannotConnectError);
|
497
504
|
};
|
498
505
|
}
|
499
506
|
|
@@ -530,6 +537,44 @@ static VALUE hiredis_write(VALUE self, VALUE command) {
|
|
530
537
|
return Qnil;
|
531
538
|
}
|
532
539
|
|
540
|
+
typedef struct {
|
541
|
+
redisContext *context;
|
542
|
+
int return_value;
|
543
|
+
} hiredis_buffer_read_args_t;
|
544
|
+
|
545
|
+
void *hiredis_buffer_read_safe(void *_args) {
|
546
|
+
hiredis_buffer_read_args_t *args = _args;
|
547
|
+
args->return_value = redisBufferRead(args->context);
|
548
|
+
return NULL;
|
549
|
+
}
|
550
|
+
int hiredis_buffer_read_nogvl(redisContext *context) {
|
551
|
+
hiredis_buffer_read_args_t args = {
|
552
|
+
.context = context,
|
553
|
+
};
|
554
|
+
rb_thread_call_without_gvl(hiredis_buffer_read_safe, &args, RUBY_UBF_IO, 0);
|
555
|
+
return args.return_value;
|
556
|
+
}
|
557
|
+
|
558
|
+
typedef struct {
|
559
|
+
redisContext *context;
|
560
|
+
int *done;
|
561
|
+
int return_value;
|
562
|
+
} hiredis_buffer_write_args_t;
|
563
|
+
|
564
|
+
void *hiredis_buffer_write_safe(void *_args) {
|
565
|
+
hiredis_buffer_write_args_t *args = _args;
|
566
|
+
args->return_value = redisBufferWrite(args->context, args->done);
|
567
|
+
return NULL;
|
568
|
+
}
|
569
|
+
int hiredis_buffer_write_nogvl(redisContext *context, int *done) {
|
570
|
+
hiredis_buffer_write_args_t args = {
|
571
|
+
.context = context,
|
572
|
+
.done = done,
|
573
|
+
};
|
574
|
+
rb_thread_call_without_gvl(hiredis_buffer_write_safe, &args, RUBY_UBF_IO, 0);
|
575
|
+
return args.return_value;
|
576
|
+
}
|
577
|
+
|
533
578
|
static VALUE hiredis_flush(VALUE self) {
|
534
579
|
CONNECTION(self, connection);
|
535
580
|
ENSURE_CONNECTED(connection);
|
@@ -537,7 +582,7 @@ static VALUE hiredis_flush(VALUE self) {
|
|
537
582
|
int wdone = 0;
|
538
583
|
while (!wdone) {
|
539
584
|
errno = 0;
|
540
|
-
if (
|
585
|
+
if (hiredis_buffer_write_nogvl(connection->context, &wdone) == REDIS_ERR) {
|
541
586
|
if (errno == EAGAIN) {
|
542
587
|
int writable = 0;
|
543
588
|
|
@@ -573,7 +618,7 @@ static int hiredis_read_internal(hiredis_connection_t *connection, VALUE *reply)
|
|
573
618
|
while (!wdone) {
|
574
619
|
errno = 0;
|
575
620
|
|
576
|
-
if (
|
621
|
+
if (hiredis_buffer_write_nogvl(connection->context, &wdone) == REDIS_ERR) {
|
577
622
|
/* Socket error */
|
578
623
|
return -1;
|
579
624
|
}
|
@@ -596,7 +641,7 @@ static int hiredis_read_internal(hiredis_connection_t *connection, VALUE *reply)
|
|
596
641
|
while (redis_reply == NULL) {
|
597
642
|
errno = 0;
|
598
643
|
|
599
|
-
if (
|
644
|
+
if (hiredis_buffer_read_nogvl(connection->context) == REDIS_ERR) {
|
600
645
|
/* Socket error */
|
601
646
|
return -1;
|
602
647
|
}
|
@@ -665,9 +710,6 @@ void Init_hiredis_connection(void) {
|
|
665
710
|
id_add = rb_intern("add");
|
666
711
|
id_new = rb_intern("new");
|
667
712
|
|
668
|
-
rb_cSet = rb_const_get(rb_cObject, rb_intern("Set"));
|
669
|
-
rb_global_variable(&rb_cSet);
|
670
|
-
|
671
713
|
VALUE rb_cRedisClient = rb_const_get(rb_cObject, rb_intern("RedisClient"));
|
672
714
|
|
673
715
|
rb_eRedisClientCommandError = rb_const_get(rb_cRedisClient, rb_intern("CommandError"));
|
@@ -676,8 +718,11 @@ void Init_hiredis_connection(void) {
|
|
676
718
|
rb_eRedisClientConnectionError = rb_const_get(rb_cRedisClient, rb_intern("ConnectionError"));
|
677
719
|
rb_global_variable(&rb_eRedisClientConnectionError);
|
678
720
|
|
679
|
-
|
680
|
-
rb_global_variable(&
|
721
|
+
rb_eRedisClientCannotConnectError = rb_const_get(rb_cRedisClient, rb_intern("CannotConnectError"));
|
722
|
+
rb_global_variable(&rb_eRedisClientCannotConnectError);
|
723
|
+
|
724
|
+
rb_eRedisClientProtocolError = rb_const_get(rb_cRedisClient, rb_intern("ProtocolError"));
|
725
|
+
rb_global_variable(&rb_eRedisClientProtocolError);
|
681
726
|
|
682
727
|
rb_eRedisClientReadTimeoutError = rb_const_get(rb_cRedisClient, rb_intern("ReadTimeoutError"));
|
683
728
|
rb_global_variable(&rb_eRedisClientReadTimeoutError);
|
@@ -34,7 +34,11 @@ class RedisClient
|
|
34
34
|
self.write_timeout = write_timeout
|
35
35
|
|
36
36
|
if config.path
|
37
|
-
|
37
|
+
begin
|
38
|
+
connect_unix(config.path)
|
39
|
+
rescue SystemCallError => error
|
40
|
+
raise CannotConnectError, error.message, error.backtrace
|
41
|
+
end
|
38
42
|
else
|
39
43
|
connect_tcp(config.host, config.port)
|
40
44
|
end
|
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.6.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-08-16 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.6.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.6.0
|
27
27
|
description:
|
28
28
|
email:
|
29
29
|
- jean.boussier@gmail.com
|