hiredis-client 0.14.0 → 0.15.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: 767ca647924d14a2509280e51bee10968a669b9ea1e2df60f4fee4c8be4d3f0f
4
- data.tar.gz: eebad74d4427e86f5c94ec6d83e0cb5aa55bd2826fd150190d5a0fabd4c64fea
3
+ metadata.gz: d85790ae197a6affc3f442a07dc13207b600821dba1a840b773aa54e6dd9b6df
4
+ data.tar.gz: 5e4e61dfa45511e1ebe56681fa55ef121900155b1a5db8724f45a23111dbcb21
5
5
  SHA512:
6
- metadata.gz: ca70fbf8254d7101b8b63ffb223d0530b8c7fb2854cb667ff0093f62fb10be848ca9153b123bf5a5ae1988bf61b63f0afcd7abb0b552e7ae35c5f52ac1aa2e1f
7
- data.tar.gz: 1affad896f66ddd864619b1786586f0d9f352aa741f873d6ca69cbb37b41a37020c7c9391f8431011a532f49346f5d8712bca32be2c15d5ade449cafa3c2b421
6
+ metadata.gz: 19be40f01d83e960305cc29b719578124f4a11189c60431c4a9337174a462c2ede846c00a53d166485ddc4208f68c4641263d03533fad783998ad64685941e4b
7
+ data.tar.gz: b1ee30444e242333a3920acb864f943523312b6ad34eeec3bd09cef421c611d4b26267bf1a7d61559fba66055bbd08afd8a75b417c63080afa5bb2bc73efaf7d
@@ -36,9 +36,12 @@
36
36
  #include <errno.h>
37
37
  #include <sys/socket.h>
38
38
  #include <stdbool.h>
39
+ #include <unistd.h>
40
+ #include <fcntl.h>
39
41
  #include "hiredis.h"
40
42
  #include "net.h"
41
43
  #include "hiredis_ssl.h"
44
+ #include <poll.h>
42
45
 
43
46
  #if !defined(RUBY_ASSERT)
44
47
  # define RUBY_ASSERT(condition) ((void)0)
@@ -797,6 +800,120 @@ static VALUE hiredis_close(VALUE self) {
797
800
  return Qnil;
798
801
  }
799
802
 
803
+ static VALUE hiredis_reopen(VALUE self) {
804
+ CONNECTION(self, connection);
805
+ if (!connection->context) {
806
+ return Qfalse;
807
+ }
808
+
809
+ if (connection->context->fd == REDIS_INVALID_FD) {
810
+ return Qfalse;
811
+ }
812
+
813
+ int null_fd = open("/dev/null", O_RDWR | O_CLOEXEC);
814
+ if (null_fd <= 0) {
815
+ return Qfalse;
816
+ }
817
+
818
+ int rc = dup2(null_fd, connection->context->fd);
819
+ if (close(null_fd) < 0) {
820
+ return Qfalse;
821
+ }
822
+
823
+ if (rc < 0) {
824
+ return Qfalse;
825
+ }
826
+
827
+ return Qtrue;
828
+ }
829
+
830
+ static inline double diff_timespec_ms(const struct timespec *time1, const struct timespec *time0) {
831
+ return ((time1->tv_sec - time0->tv_sec) * 1000.0)
832
+ + (time1->tv_nsec - time0->tv_nsec) / 1000000.0;
833
+ }
834
+
835
+ static inline int timeval_to_msec(struct timeval duration) {
836
+ return duration.tv_sec * 1000 + duration.tv_usec / 1000;
837
+ }
838
+
839
+ typedef struct {
840
+ hiredis_connection_t *connection;
841
+ struct timespec start;
842
+ struct timespec end;
843
+ int return_value;
844
+ } hiredis_measure_round_trip_delay_args_t;
845
+
846
+ static const size_t pong_length = 7;
847
+
848
+ static void *hiredis_measure_round_trip_delay_safe(void *_args) {
849
+ hiredis_measure_round_trip_delay_args_t *args = _args;
850
+ hiredis_connection_t *connection = args->connection;
851
+ redisReader *reader = connection->context->reader;
852
+
853
+ if (reader->len - reader->pos != 0) {
854
+ args->return_value = REDIS_ERR;
855
+ return NULL;
856
+ }
857
+
858
+ redisAppendFormattedCommand(connection->context, "PING\r\n", 6);
859
+
860
+ clock_gettime(CLOCK_MONOTONIC, &args->start);
861
+
862
+ int wdone = 0;
863
+ do {
864
+ if (redisBufferWrite(connection->context, &wdone) == REDIS_ERR) {
865
+ args->return_value = REDIS_ERR;
866
+ return NULL;
867
+ }
868
+ } while (!wdone);
869
+
870
+ struct pollfd wfd[1];
871
+ wfd[0].fd = connection->context->fd;
872
+ wfd[0].events = POLLIN;
873
+ int retval = poll(wfd, 1, timeval_to_msec(connection->read_timeout));
874
+ if (retval == -1) {
875
+ args->return_value = REDIS_ERR_IO;
876
+ return NULL;
877
+ } else if (!retval) {
878
+ args->return_value = REDIS_ERR_IO;
879
+ return NULL;
880
+ }
881
+
882
+ redisBufferRead(connection->context);
883
+
884
+ if (reader->len - reader->pos != pong_length) {
885
+ args->return_value = REDIS_ERR;
886
+ return NULL;
887
+ }
888
+
889
+ if (strncmp(reader->buf + reader->pos, "+PONG\r\n", pong_length) != 0) {
890
+ args->return_value = REDIS_ERR;
891
+ return NULL;
892
+ }
893
+ reader->pos += pong_length;
894
+
895
+ clock_gettime(CLOCK_MONOTONIC, &args->end);
896
+ args->return_value = REDIS_OK;
897
+ return NULL;
898
+ }
899
+
900
+ static VALUE hiredis_measure_round_trip_delay(VALUE self) {
901
+ CONNECTION(self, connection);
902
+ ENSURE_CONNECTED(connection);
903
+
904
+ hiredis_measure_round_trip_delay_args_t args = {
905
+ .connection = connection,
906
+ };
907
+ rb_thread_call_without_gvl(hiredis_measure_round_trip_delay_safe, &args, RUBY_UBF_IO, 0);
908
+
909
+ if (args.return_value != REDIS_OK) {
910
+ hiredis_raise_error_and_disconnect(connection, rb_eRedisClientReadTimeoutError);
911
+ return Qnil; // unreachable;
912
+ }
913
+
914
+ return DBL2NUM(diff_timespec_ms(&args.end, &args.start));
915
+ }
916
+
800
917
  RUBY_FUNC_EXPORTED void Init_hiredis_connection(void) {
801
918
  // Qfalse == NULL, so we can't return Qfalse in `reply_create_bool()`
802
919
  RUBY_ASSERT((void *)Qfalse == NULL);
@@ -843,6 +960,8 @@ RUBY_FUNC_EXPORTED void Init_hiredis_connection(void) {
843
960
  rb_define_private_method(rb_cHiredisConnection, "_read", hiredis_read, 0);
844
961
  rb_define_private_method(rb_cHiredisConnection, "flush", hiredis_flush, 0);
845
962
  rb_define_private_method(rb_cHiredisConnection, "_close", hiredis_close, 0);
963
+ rb_define_private_method(rb_cHiredisConnection, "_reopen", hiredis_reopen, 0);
964
+ rb_define_method(rb_cHiredisConnection, "measure_round_trip_delay", hiredis_measure_round_trip_delay, 0);
846
965
 
847
966
  VALUE rb_cHiredisSSLContext = rb_define_class_under(rb_cHiredisConnection, "SSLContext", rb_cObject);
848
967
  rb_define_alloc_func(rb_cHiredisSSLContext, hiredis_ssl_context_alloc);
@@ -10,6 +10,17 @@ class RedisClient
10
10
 
11
11
  class << self
12
12
  def ssl_context(ssl_params)
13
+ unless ssl_params[:ca_file] || ssl_params[:ca_path]
14
+ default_ca_file = OpenSSL::X509::DEFAULT_CERT_FILE
15
+ default_ca_path = OpenSSL::X509::DEFAULT_CERT_DIR
16
+
17
+ if File.readable? default_ca_file
18
+ ssl_params[:ca_file] = default_ca_file
19
+ elsif File.directory? default_ca_path
20
+ ssl_params[:ca_path] = default_ca_path
21
+ end
22
+ end
23
+
13
24
  HiredisConnection::SSLContext.new(
14
25
  ca_file: ssl_params[:ca_file],
15
26
  ca_path: ssl_params[:ca_path],
@@ -42,6 +53,11 @@ class RedisClient
42
53
  super
43
54
  end
44
55
 
56
+ def discard
57
+ _reopen
58
+ close
59
+ end
60
+
45
61
  def reconnect
46
62
  reconnected = begin
47
63
  _reconnect(@config.path, @config.ssl_context)
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.14.0
4
+ version: 0.15.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: 2023-03-10 00:00:00.000000000 Z
11
+ date: 2023-08-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.14.0
19
+ version: 0.15.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.14.0
26
+ version: 0.15.0
27
27
  description:
28
28
  email:
29
29
  - jean.boussier@gmail.com
@@ -105,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
105
  - !ruby/object:Gem::Version
106
106
  version: '0'
107
107
  requirements: []
108
- rubygems_version: 3.4.6
108
+ rubygems_version: 3.3.7
109
109
  signing_key:
110
110
  specification_version: 4
111
111
  summary: Hiredis binding for redis-client