valkey-glide-sync 2.2.6__tar.gz → 2.2.7__tar.gz

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.
Files changed (157) hide show
  1. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/PKG-INFO +1 -1
  2. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster.rs +3 -0
  3. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_async/mod.rs +198 -88
  4. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_async/pipeline_routing.rs +8 -0
  5. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/connection.rs +2 -2
  6. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/types.rs +3 -1
  7. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/pyproject.toml +1 -1
  8. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/valkey_glide_sync.egg-info/PKG-INFO +1 -1
  9. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/MANIFEST.in +0 -0
  10. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/README.md +0 -0
  11. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/.cargo/config.toml +0 -0
  12. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/.gitignore +0 -0
  13. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/.ort.yml +0 -0
  14. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/Cargo.toml +0 -0
  15. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/DEVELOPER.md +0 -0
  16. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/README.md +0 -0
  17. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/cbindgen.toml +0 -0
  18. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/Cargo.toml +0 -0
  19. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/README.md +0 -0
  20. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/Cargo.toml +0 -0
  21. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/client.rs +0 -0
  22. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/cluster_scan_container.rs +0 -0
  23. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/command_request.rs +0 -0
  24. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/connection_request.rs +0 -0
  25. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/errors.rs +0 -0
  26. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/lib.rs +0 -0
  27. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/request_type.rs +0 -0
  28. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-glide-core/src/scripts_container.rs +0 -0
  29. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-logger-core/Cargo.toml +0 -0
  30. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-logger-core/src/lib.rs +0 -0
  31. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-redis/Cargo.toml +0 -0
  32. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-redis/src/cluster_routing.rs +0 -0
  33. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-redis/src/cluster_topology.rs +0 -0
  34. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-redis/src/lib.rs +0 -0
  35. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-telemetry/Cargo.toml +0 -0
  36. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-telemetry/src/lib.rs +0 -0
  37. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-tokio/Cargo.toml +0 -0
  38. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-tokio/src/lib.rs +0 -0
  39. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-tokio/src/runtime.rs +0 -0
  40. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-tokio/src/sync.rs +0 -0
  41. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/mock-tokio/src/task.rs +0 -0
  42. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/miri-tests/rust-toolchain.toml +0 -0
  43. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/ffi/src/lib.rs +0 -0
  44. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/.cargo/config.toml +0 -0
  45. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/.ort.yml +0 -0
  46. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/Cargo.toml +0 -0
  47. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/README.md +0 -0
  48. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/THIRD_PARTY_LICENSES_RUST +0 -0
  49. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/build.rs +0 -0
  50. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/Cargo.toml +0 -0
  51. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/LICENSE +0 -0
  52. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/README.md +0 -0
  53. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/appveyor.yml +0 -0
  54. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/get_command_info.py +0 -0
  55. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/CHANGELOG.md +0 -0
  56. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/Cargo.toml +0 -0
  57. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/LICENSE +0 -0
  58. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/examples/async-await.rs +0 -0
  59. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/examples/async-multiplexed.rs +0 -0
  60. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/examples/async-pub-sub.rs +0 -0
  61. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/examples/async-scan.rs +0 -0
  62. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/examples/basic.rs +0 -0
  63. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/release.toml +0 -0
  64. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/aio/connection.rs +0 -0
  65. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/aio/connection_manager.rs +0 -0
  66. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/aio/mod.rs +0 -0
  67. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/aio/multiplexed_connection.rs +0 -0
  68. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/aio/runtime.rs +0 -0
  69. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/aio/tokio.rs +0 -0
  70. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/client.rs +0 -0
  71. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_async/LICENSE +0 -0
  72. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_async/connections_container.rs +0 -0
  73. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_async/connections_logic.rs +0 -0
  74. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_client.rs +0 -0
  75. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_pipeline.rs +0 -0
  76. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_routing.rs +0 -0
  77. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_slotmap.rs +0 -0
  78. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cluster_topology.rs +0 -0
  79. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/cmd.rs +0 -0
  80. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/commands/cluster_scan.rs +0 -0
  81. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/commands/macros.rs +0 -0
  82. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/commands/mod.rs +0 -0
  83. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/lib.rs +0 -0
  84. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/macros.rs +0 -0
  85. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/parser.rs +0 -0
  86. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/pipeline.rs +0 -0
  87. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/push_manager.rs +0 -0
  88. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/retry_strategies.rs +0 -0
  89. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/sentinel.rs +0 -0
  90. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/redis/src/tls.rs +0 -0
  91. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/rustfmt.toml +0 -0
  92. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/redis-rs/src/main.rs +0 -0
  93. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/client/mod.rs +0 -0
  94. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/client/reconnecting_connection.rs +0 -0
  95. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/client/standalone_client.rs +0 -0
  96. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/client/types.rs +0 -0
  97. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/client/value_conversion.rs +0 -0
  98. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/cluster_scan_container.rs +0 -0
  99. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/errors.rs +0 -0
  100. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/iam/mod.rs +0 -0
  101. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/lib.rs +0 -0
  102. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/protobuf/command_request.proto +0 -0
  103. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/protobuf/connection_request.proto +0 -0
  104. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/protobuf/response.proto +0 -0
  105. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/request_type.rs +0 -0
  106. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/rotating_buffer.rs +0 -0
  107. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/scripts_container.rs +0 -0
  108. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/src/socket_listener.rs +0 -0
  109. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/telemetry/Cargo.toml +0 -0
  110. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/telemetry/src/lib.rs +0 -0
  111. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/telemetry/src/metrics_exporter_file.rs +0 -0
  112. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/telemetry/src/open_telemetry.rs +0 -0
  113. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide-core/telemetry/src/span_exporter_file.rs +0 -0
  114. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/__init__.py +0 -0
  115. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/__init__.py +0 -0
  116. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/batch.py +0 -0
  117. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/batch_options.py +0 -0
  118. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/bitmap.py +0 -0
  119. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/command_args.py +0 -0
  120. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/core_options.py +0 -0
  121. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/server_modules/ft_options/ft_aggregate_options.py +0 -0
  122. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/server_modules/ft_options/ft_constants.py +0 -0
  123. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/server_modules/ft_options/ft_create_options.py +0 -0
  124. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/server_modules/ft_options/ft_profile_options.py +0 -0
  125. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/server_modules/ft_options/ft_search_options.py +0 -0
  126. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/server_modules/json_batch.py +0 -0
  127. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/server_modules/json_options.py +0 -0
  128. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/sorted_set.py +0 -0
  129. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/commands/stream.py +0 -0
  130. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/config.py +0 -0
  131. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/constants.py +0 -0
  132. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/exceptions.py +0 -0
  133. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/protobuf_codec.py +0 -0
  134. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/py.typed +0 -0
  135. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_shared/routes.py +0 -0
  136. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/__init__.py +0 -0
  137. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/_glide_ffi.py +0 -0
  138. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/config.py +0 -0
  139. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/glide_client.py +0 -0
  140. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/logger.py +0 -0
  141. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/py.typed +0 -0
  142. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/__init__.py +0 -0
  143. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/cluster_commands.py +0 -0
  144. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/cluster_scan_cursor.py +0 -0
  145. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/core.py +0 -0
  146. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/ft.py +0 -0
  147. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/glide_json.py +0 -0
  148. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/script.py +0 -0
  149. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/glide_sync/sync_commands/standalone_commands.py +0 -0
  150. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/logger_core/Cargo.toml +0 -0
  151. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/logger_core/src/lib.rs +0 -0
  152. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/setup.cfg +0 -0
  153. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/setup.py +0 -0
  154. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/valkey_glide_sync.egg-info/SOURCES.txt +0 -0
  155. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/valkey_glide_sync.egg-info/dependency_links.txt +0 -0
  156. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/valkey_glide_sync.egg-info/requires.txt +0 -0
  157. {valkey_glide_sync-2.2.6 → valkey_glide_sync-2.2.7}/valkey_glide_sync.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: valkey-glide-sync
3
- Version: 2.2.6
3
+ Version: 2.2.7
4
4
  Summary: Valkey GLIDE Sync client. Supports Valkey and Redis OSS.
5
5
  License: Apache-2.0
6
6
  Classifier: Topic :: Database
@@ -787,6 +787,9 @@ where
787
787
  }
788
788
  }
789
789
  }
790
+ RetryMethod::RefreshSlotsAndRetry => {
791
+ self.refresh_slots()?;
792
+ }
790
793
  RetryMethod::NoRetry => {
791
794
  return Err(err);
792
795
  }
@@ -953,8 +953,10 @@ impl<C> Future for Request<C> {
953
953
  let retry_method = err.retry_method();
954
954
  let next = if err.kind() == ErrorKind::AllConnectionsUnavailable {
955
955
  Next::ReconnectToInitialNodes { request: None }.into()
956
- } else if matches!(err.retry_method(), RetryMethod::MovedRedirect)
957
- || matches!(target, OperationTarget::NotFound)
956
+ } else if matches!(
957
+ err.retry_method(),
958
+ RetryMethod::MovedRedirect | RetryMethod::RefreshSlotsAndRetry
959
+ ) || matches!(target, OperationTarget::NotFound)
958
960
  {
959
961
  Next::RefreshSlots {
960
962
  request: None,
@@ -1050,6 +1052,16 @@ impl<C> Future for Request<C> {
1050
1052
  }
1051
1053
  .into()
1052
1054
  }
1055
+ RetryMethod::RefreshSlotsAndRetry => {
1056
+ let mut request = this.request.take().unwrap();
1057
+ request.info.reset_routing();
1058
+ Next::RefreshSlots {
1059
+ request: Some(request),
1060
+ sleep_duration: Some(sleep_duration),
1061
+ moved_redirect: None,
1062
+ }
1063
+ .into()
1064
+ }
1053
1065
  RetryMethod::WaitAndRetry => {
1054
1066
  let sleep_duration = this.retry_params.wait_time_for_retry(request.retry);
1055
1067
  // Sleep and retry.
@@ -1367,7 +1379,20 @@ where
1367
1379
  // This function serves as a cheap alternative to slot_refresh() and thus can be used much more frequently.
1368
1380
  // The function does not discover the topology from the cluster and assumes the cached topology is valid.
1369
1381
  // In addition, the validation is done by peeking at the state of the underlying transport w/o overhead of additional commands to server.
1382
+ // If we're during slot refresh, we skip the validation to avoid interfering with the slot refresh process.
1370
1383
  async fn validate_all_user_connections(inner: Arc<InnerCore<C>>) {
1384
+ // If slot refresh is in progress, skip validation
1385
+ // The reason is that during slot refresh, connections might be created before being assigned slots,
1386
+ // and we don't want to drop those connections and interfere with that process.
1387
+ //
1388
+ // Note: This is a best-effort check due to a potential race condition - both tasks
1389
+ // are spawned to tokio's multi-threaded runtime and can run in parallel, so
1390
+ // `refresh_slots` could start right after this check returns false.
1391
+ // TODO: Implement more robust synchronization - see https://github.com/valkey-io/valkey-glide/issues/5227
1392
+ if inner.slot_refresh_state.in_progress.load(Ordering::Relaxed) {
1393
+ return;
1394
+ }
1395
+
1371
1396
  let mut all_valid_conns = HashMap::new();
1372
1397
  // prep connections and clean out these w/o assigned slots, as we might have established connections to unwanted hosts
1373
1398
  let mut nodes_to_delete = Vec::new();
@@ -2271,7 +2296,8 @@ where
2271
2296
  ) -> RedisResult<()> {
2272
2297
  let num_of_nodes = inner.conn_lock.read().expect(MUTEX_READ_ERR).len();
2273
2298
  const MAX_REQUESTED_NODES: usize = 10;
2274
- let num_of_nodes_to_query = std::cmp::min(num_of_nodes, MAX_REQUESTED_NODES);
2299
+ let num_of_nodes_to_query = num_of_nodes.min(MAX_REQUESTED_NODES);
2300
+
2275
2301
  let (new_slots, topology_hash) = calculate_topology_from_random_nodes(
2276
2302
  &inner,
2277
2303
  num_of_nodes_to_query,
@@ -2280,75 +2306,87 @@ where
2280
2306
  )
2281
2307
  .await
2282
2308
  .topology_result?;
2309
+
2283
2310
  // Create a new connection vector of the found nodes
2284
2311
  let nodes = new_slots.all_node_addresses();
2285
2312
  let nodes_len = nodes.len();
2286
- let addresses_and_connections_iter = stream::iter(nodes)
2287
- .fold(
2288
- Vec::with_capacity(nodes_len),
2289
- |mut addrs_and_conns, addr| {
2290
- let inner = inner.clone();
2291
- async move {
2292
- let addr = addr.to_string();
2293
- if let Some(node) = inner
2294
- .conn_lock
2295
- .read()
2296
- .expect(MUTEX_READ_ERR)
2297
- .node_for_address(addr.as_str())
2298
- {
2299
- addrs_and_conns.push((addr, Some(node)));
2300
- return addrs_and_conns;
2301
- }
2302
- // If it's a DNS endpoint, it could have been stored in the existing connections vector using the resolved IP address instead of the DNS endpoint's name.
2303
- // We shall check if a connection is already exists under the resolved IP name.
2304
- let Some((host, port)) = get_host_and_port_from_addr(&addr) else {
2305
- addrs_and_conns.push((addr, None));
2306
- return addrs_and_conns;
2307
- };
2308
- let conn = get_socket_addrs(host, port)
2309
- .await
2310
- .ok()
2311
- .map(|mut socket_addresses| {
2312
- socket_addresses.find_map(|addr| {
2313
- inner
2314
- .conn_lock
2315
- .read()
2316
- .expect(MUTEX_READ_ERR)
2317
- .node_for_address(&addr.to_string())
2318
- })
2319
- })
2320
- .unwrap_or(None);
2321
- addrs_and_conns.push((addr, conn));
2322
- addrs_and_conns
2323
- }
2324
- },
2325
- )
2326
- .await;
2327
- let new_connections: ConnectionMap<C> = stream::iter(addresses_and_connections_iter)
2328
- .fold(
2329
- ConnectionsMap(DashMap::with_capacity(nodes_len)),
2330
- |connections, (addr, node)| async {
2331
- let mut cluster_params = inner
2332
- .get_cluster_param(|params| params.clone())
2333
- .expect(MUTEX_READ_ERR);
2334
- let subs_guard = inner.subscriptions_by_address.read().await;
2335
- cluster_params.pubsub_subscriptions = subs_guard.get(&addr).cloned();
2336
- drop(subs_guard);
2337
- let node = get_or_create_conn(
2338
- &addr,
2339
- node,
2340
- &cluster_params,
2341
- RefreshConnectionType::AllConnections,
2342
- inner.glide_connection_options.clone(),
2343
- )
2344
- .await;
2345
- if let Ok(node) = node {
2346
- connections.0.insert(addr, node);
2347
- }
2348
- connections
2349
- },
2350
- )
2351
- .await;
2313
+
2314
+ // Find existing connections or resolve DNS addresses
2315
+ // TODO: optimize by parallelizing DNS lookups - DNS resolution may involve network I/O and is currently performed sequentially
2316
+ // Issue link: https://github.com/valkey-io/valkey-glide/issues/5228
2317
+ let mut addresses_and_connections = Vec::with_capacity(nodes_len);
2318
+ for addr in nodes {
2319
+ let addr = addr.to_string();
2320
+
2321
+ // Check for existing connection by address
2322
+ if let Some(node) = inner
2323
+ .conn_lock
2324
+ .read()
2325
+ .expect(MUTEX_READ_ERR)
2326
+ .node_for_address(&addr)
2327
+ {
2328
+ addresses_and_connections.push((addr, Some(node)));
2329
+ continue;
2330
+ }
2331
+
2332
+ // If it's a DNS endpoint, it could have been stored in the existing connections vector using the resolved IP address instead of the DNS endpoint's name.
2333
+ // We shall check if a connection is already exists under the resolved IP name.
2334
+ let conn = if let Some((host, port)) = get_host_and_port_from_addr(&addr) {
2335
+ get_socket_addrs(host, port)
2336
+ .await
2337
+ .ok()
2338
+ .and_then(|mut socket_addresses| {
2339
+ let conn_lock = inner.conn_lock.read().expect(MUTEX_READ_ERR);
2340
+ socket_addresses.find_map(|socket_addr| {
2341
+ conn_lock.node_for_address(&socket_addr.to_string())
2342
+ })
2343
+ })
2344
+ } else {
2345
+ None
2346
+ };
2347
+
2348
+ addresses_and_connections.push((addr, conn));
2349
+ }
2350
+
2351
+ let cluster_params = inner
2352
+ .get_cluster_param(|params| params.clone())
2353
+ .expect(MUTEX_READ_ERR);
2354
+ let glide_connection_options = &inner.glide_connection_options;
2355
+
2356
+ let subs_guard = inner.subscriptions_by_address.read().await;
2357
+ let subscriptions_snapshot: HashMap<_, _> = subs_guard.clone();
2358
+ drop(subs_guard);
2359
+
2360
+ // Create/retrieve connections in for found nodes
2361
+ let connection_futures = addresses_and_connections.into_iter().map(|(addr, node)| {
2362
+ let mut cluster_params = cluster_params.clone();
2363
+ let glide_connection_options = glide_connection_options.clone();
2364
+ cluster_params.pubsub_subscriptions = subscriptions_snapshot.get(&addr).cloned();
2365
+ async move {
2366
+ let result = get_or_create_conn(
2367
+ &addr,
2368
+ node,
2369
+ &cluster_params,
2370
+ RefreshConnectionType::AllConnections,
2371
+ glide_connection_options,
2372
+ )
2373
+ .await;
2374
+ (addr, result)
2375
+ }
2376
+ });
2377
+
2378
+ // Await all connection futures
2379
+ // This is bounded by `connection_timeout` since `get_or_create_conn` uses it internally,
2380
+ // so it is safe to await them all at once.
2381
+ let results = futures::future::join_all(connection_futures).await;
2382
+
2383
+ // Collect successful connections
2384
+ let new_connections = ConnectionsMap(DashMap::with_capacity(nodes_len));
2385
+ for (addr, result) in results {
2386
+ if let Ok(node) = result {
2387
+ new_connections.0.insert(addr, node);
2388
+ }
2389
+ }
2352
2390
 
2353
2391
  info!("refresh_slots found nodes:\n{new_connections}");
2354
2392
  // Reset the current slot map and connection vector with the new ones
@@ -3451,7 +3489,30 @@ struct InitialNodeConnectionsResult<C> {
3451
3489
  }
3452
3490
 
3453
3491
  /// Returns connections found for randomly selected initial nodes, along with addresses
3454
- /// that need refresh and a hint if topology change was detected.
3492
+ /// that needs to be refreshed.
3493
+ ///
3494
+ /// # Lookup and Retry Logic
3495
+ ///
3496
+ /// 1. **Resolve initial nodes**: Expand the configured initial nodes to their underlying addresses.
3497
+ /// A single initial node may resolve to multiple addresses (e.g., DNS hostnames resolving to
3498
+ /// multiple IP addresses).
3499
+ /// 2. **Random selection**: Pick `num_of_nodes_to_query` random nodes from the resolved list
3500
+ /// 3. **Connection lookup**: For each selected node, attempt to find an existing connection,
3501
+ /// preferring a management connection when available.
3502
+ ///
3503
+ /// ## Retry Mechanism
3504
+ ///
3505
+ /// If **no connections** are found in the initial lookup (all selected nodes need refresh),
3506
+ /// the function performs a single retry:
3507
+ ///
3508
+ /// 1. Trigger connection refresh for all missing addresses
3509
+ /// 2. Wait for refresh to complete (with `connection_timeout`)
3510
+ /// 3. Retry the connection lookup for those addresses
3511
+ ///
3512
+ /// # Returns
3513
+ ///
3514
+ /// * `connections` - List of found connections (may be empty if all lookups failed)
3515
+ /// * `addresses_needing_refresh` - Addresses that needs to be refreshed
3455
3516
  async fn get_random_connections_from_initial_nodes<C>(
3456
3517
  inner: &Core<C>,
3457
3518
  num_of_nodes_to_query: usize,
@@ -3481,7 +3542,7 @@ where
3481
3542
  let mut addresses_needing_refresh = HashSet::new();
3482
3543
 
3483
3544
  for (original_addr, socket_addr) in selected_pairs {
3484
- match lookup_management_connection(inner, &original_addr, socket_addr.map(|s| s.ip())) {
3545
+ match lookup_management_connection(inner, &original_addr, socket_addr) {
3485
3546
  ConnectionLookupResult::Found(conn) => connections.push(conn),
3486
3547
  ConnectionLookupResult::NeedsConnectionRefresh(addr) => {
3487
3548
  addresses_needing_refresh.insert(addr);
@@ -3489,6 +3550,35 @@ where
3489
3550
  }
3490
3551
  }
3491
3552
 
3553
+ // Only refresh and retry if we have no connections at all
3554
+ if connections.is_empty() && !addresses_needing_refresh.is_empty() {
3555
+ let connection_timeout = inner.get_cluster_param(|p| p.connection_timeout)?;
3556
+
3557
+ // Wait for connection refresh to complete (with timeout)
3558
+ let _ = tokio::time::timeout(
3559
+ connection_timeout,
3560
+ ClusterConnInner::refresh_and_update_connections(
3561
+ inner.clone(),
3562
+ addresses_needing_refresh.clone(),
3563
+ RefreshConnectionType::AllConnections,
3564
+ true,
3565
+ ),
3566
+ )
3567
+ .await;
3568
+
3569
+ let mut still_need_refresh = HashSet::new();
3570
+ for addr in addresses_needing_refresh.drain() {
3571
+ if let ConnectionLookupResult::Found(conn) =
3572
+ lookup_management_connection(inner, &addr, None)
3573
+ {
3574
+ connections.push(conn);
3575
+ } else {
3576
+ still_need_refresh.insert(addr);
3577
+ }
3578
+ }
3579
+ addresses_needing_refresh = still_need_refresh;
3580
+ }
3581
+
3492
3582
  Ok(InitialNodeConnectionsResult {
3493
3583
  connections,
3494
3584
  addresses_needing_refresh,
@@ -3507,22 +3597,36 @@ enum ConnectionLookupResult<C> {
3507
3597
  /// Finds a management connection for a node or indicates it needs refresh.
3508
3598
  /// Returns the management connection if available, otherwise falls back to user connection.
3509
3599
  ///
3600
+ /// **Warning** ⚠️: This function may have O(n) time complexity. Where `n` is the number of nodes in the slot map.
3601
+ ///
3510
3602
  /// # Arguments
3511
- /// The `original_addr` may be provided by the user either as a hostname (DNS) or as a direct IP address.
3512
- /// When a hostname is provided, we attempt to resolve it to an IP;
3513
- /// if resolution succeeds, the result is passed as `resolved_ip`.
3603
+ ///
3604
+ /// * `original_addr` - The address as provided by the user, either as a hostname (DNS)
3605
+ /// or as a direct IP address (e.g., `"cluster.example.com:6379"` or `"127.0.0.1:6379"`).
3606
+ /// * `socket_addr` - The resolved socket address if DNS resolution succeeded, or `None`
3607
+ /// if resolution failed.
3514
3608
  ///
3515
3609
  /// # Lookup Logic
3516
- /// Resolve the node's canonical name from the slot map. The canonical name is the node's
3517
- /// address as stored in the slot map (e.g., `my-cluster-001-001.xyz:6379`). The address may
3518
- /// be provided as an IP but stored as a DNS name.
3610
+ /// Resolves the node's canonical address from the slot map. The canonical address is how
3611
+ /// the node is stored in the `slot_map`, which is our source of truth (e.g., `"my-cluster-001-001.xyz:6379"`).
3612
+ /// The caller may provide `original_addr` as an IP, but the slot map may store the same node with its DNS name.
3519
3613
  ///
3520
- /// 1. Check if `original_addr` exists in the slot map as the canonical address (O(1))
3521
- /// 2. If not, search if `resolved_ip` maps to a canonical address in the slot map (O(n))
3522
- /// 3. If still not found, fall back to using `original_addr` as the canonical address
3614
+ /// The address resolution follows these steps:
3523
3615
  ///
3524
- /// Then attempt to retrieve the connection for the canonical address from the connection map, or
3525
- /// indicate that this address needs to be refreshed.
3616
+ /// 1. **Direct match**: If `original_addr` exists in the slot map, it is treated as
3617
+ /// the canonical address (O(1)).
3618
+ /// 2. **IP-based match**: Otherwise, if `socket_addr` is available, attempt to find
3619
+ /// a canonical address in the slot map that matches its IP (O(n)).
3620
+ /// 3. **Default address selection**: If no canonical address is found in the slot map,
3621
+ /// select an address to use for a potential new connection:
3622
+ /// - Prefer `socket_addr` if available
3623
+ /// - Otherwise, use `original_addr` as-is
3624
+ ///
3625
+ /// # Connection Lookup
3626
+ /// After resolving the canonical address, the function attempts to retrieve a connection
3627
+ /// for that address, preferring the management connection but falling back to the
3628
+ /// user connection if the management connection is unavailable.
3629
+ /// If not found, it indicates that a new connection needs to be established.
3526
3630
  ///
3527
3631
  /// # Returns
3528
3632
  /// * `Found` - Connection was found
@@ -3530,7 +3634,7 @@ enum ConnectionLookupResult<C> {
3530
3634
  fn lookup_management_connection<C>(
3531
3635
  inner: &Core<C>,
3532
3636
  original_addr: &str,
3533
- resolved_ip: Option<IpAddr>,
3637
+ socket_addr: Option<SocketAddr>,
3534
3638
  ) -> ConnectionLookupResult<C>
3535
3639
  where
3536
3640
  C: ConnectionLike + Connect + Clone + Send + Sync + 'static,
@@ -3540,27 +3644,33 @@ where
3540
3644
  let (canonical_addr, conn_opt) = {
3541
3645
  let conn_lock = inner.conn_lock.read().expect(MUTEX_READ_ERR);
3542
3646
 
3543
- // Resolve canonical address: slot map lookup, fallback to original_addr
3647
+ // Resolve canonical address using the lookup chain:
3544
3648
  let canonical_addr = if conn_lock
3545
3649
  .slot_map
3546
3650
  .nodes_map()
3547
3651
  .contains_key(&original_addr_key)
3548
3652
  {
3653
+ // Step 1: Direct match
3549
3654
  original_addr.to_string()
3550
3655
  } else {
3551
- resolved_ip
3552
- .and_then(|ip| {
3656
+ socket_addr
3657
+ // Step 2: IP-based match
3658
+ .and_then(|addr| {
3553
3659
  conn_lock
3554
3660
  .slot_map
3555
- .node_address_for_ip(ip)
3661
+ .node_address_for_ip(addr.ip())
3556
3662
  .map(|a| (*a).clone())
3557
3663
  })
3664
+ // Step 3: Use socket_addr if available
3665
+ .or_else(|| socket_addr.map(|addr| addr.to_string()))
3666
+ // Step 4: Last resort - use original_addr
3558
3667
  .unwrap_or_else(|| original_addr.to_string())
3559
3668
  };
3560
3669
 
3670
+ // Look up management connection, fall back to user connection if not available
3561
3671
  let conn_opt = conn_lock.management_connection_for_address(&canonical_addr);
3562
3672
  (canonical_addr, conn_opt)
3563
- }; // Lock released here
3673
+ };
3564
3674
 
3565
3675
  match conn_opt {
3566
3676
  Some(conn) => ConnectionLookupResult::Found(conn),
@@ -721,6 +721,10 @@ fn update_retry_map(
721
721
  .or_default()
722
722
  .push(((index, inner_index), address, error));
723
723
  }
724
+ RetryMethod::RefreshSlotsAndRetry => {
725
+ // TODO: Add support for refreshing slots and retrying in pipelines
726
+ // https://github.com/valkey-io/valkey-glide/issues/5226
727
+ }
724
728
  RetryMethod::RetryImmediately
725
729
  | RetryMethod::WaitAndRetry
726
730
  | RetryMethod::WaitAndRetryOnPrimaryRedirectOnReplica => {
@@ -867,6 +871,10 @@ where
867
871
  RetryMethod::NoRetry => {
868
872
  // The server error was already added to the pipeline responses, so we can just continue.
869
873
  }
874
+ RetryMethod::RefreshSlotsAndRetry => {
875
+ // TODO: Add support for refreshing slots and retrying in pipelines
876
+ // https://github.com/valkey-io/valkey-glide/issues/5226
877
+ }
870
878
  RetryMethod::Reconnect | RetryMethod::ReconnectAndRetry => {
871
879
  handle_reconnect_logic(
872
880
  indices_addresses_and_error,
@@ -983,10 +983,10 @@ fn setup_connection(
983
983
  }
984
984
  }
985
985
 
986
- if connection_info.client_name.is_some() {
986
+ if let Some(client_name) = connection_info.client_name.as_ref() {
987
987
  match cmd("CLIENT")
988
988
  .arg("SETNAME")
989
- .arg(connection_info.client_name.as_ref().unwrap())
989
+ .arg(client_name)
990
990
  .query::<Value>(&mut rv)
991
991
  {
992
992
  Ok(Value::Okay) => {}
@@ -868,6 +868,7 @@ pub(crate) enum RetryMethod {
868
868
  AskRedirect,
869
869
  MovedRedirect,
870
870
  WaitAndRetryOnPrimaryRedirectOnReplica,
871
+ RefreshSlotsAndRetry,
871
872
  }
872
873
 
873
874
  /// Indicates a general failure in the library.
@@ -1033,6 +1034,7 @@ impl RedisError {
1033
1034
  RetryMethod::AskRedirect => false,
1034
1035
  RetryMethod::MovedRedirect => false,
1035
1036
  RetryMethod::WaitAndRetryOnPrimaryRedirectOnReplica => false,
1037
+ RetryMethod::RefreshSlotsAndRetry => false,
1036
1038
  }
1037
1039
  }
1038
1040
 
@@ -1112,7 +1114,7 @@ impl RedisError {
1112
1114
  ErrorKind::BusyLoadingError => RetryMethod::WaitAndRetryOnPrimaryRedirectOnReplica,
1113
1115
 
1114
1116
  ErrorKind::ResponseError => RetryMethod::NoRetry,
1115
- ErrorKind::ReadOnly => RetryMethod::NoRetry,
1117
+ ErrorKind::ReadOnly => RetryMethod::RefreshSlotsAndRetry,
1116
1118
  ErrorKind::ExtensionError => RetryMethod::NoRetry,
1117
1119
  ErrorKind::ExecAbortError => RetryMethod::NoRetry,
1118
1120
  ErrorKind::TypeError => RetryMethod::NoRetry,
@@ -1,5 +1,5 @@
1
1
  [project]
2
- version = "2.2.6"
2
+ version = "2.2.7"
3
3
  name = "valkey-glide-sync"
4
4
  description = "Valkey GLIDE Sync client. Supports Valkey and Redis OSS."
5
5
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: valkey-glide-sync
3
- Version: 2.2.6
3
+ Version: 2.2.7
4
4
  Summary: Valkey GLIDE Sync client. Supports Valkey and Redis OSS.
5
5
  License: Apache-2.0
6
6
  Classifier: Topic :: Database