hiredis-client 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3506adf6e5b2e5da54f4fc75e762a0fd4f23b9bd9ea225a468b2ae96360d0273
4
- data.tar.gz: 484b29d8fb080fad9076e71f1db9a1703b9b2a3a5ae173b6a5073d5abb2bfbe6
3
+ metadata.gz: d85790ae197a6affc3f442a07dc13207b600821dba1a840b773aa54e6dd9b6df
4
+ data.tar.gz: 5e4e61dfa45511e1ebe56681fa55ef121900155b1a5db8724f45a23111dbcb21
5
5
  SHA512:
6
- metadata.gz: 3e238fe1e94a808f6c1966c8c2ce1136fa173594cfa824156199c3509b3b61c8b9f97a75336458edf7c50dcddc7a7d08833358a9f34bf64f141587fb1f19fa74
7
- data.tar.gz: a6ddda3ab9d41f591cd82c1319fd43fc701cbb0c515768e0d940bc095fc69c69334bbf932c860ab37944a7f73e141a5e6b25fc4a2de454fb726f4dd199fadf48
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.1
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-30 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.1
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.1
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