hiredis-client 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|