solid-redis 1.0.9 → 1.0.10
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/CHANGELOG.md +15 -0
- data/README.md +47 -54
- data/lib/solid_redis/cluster/command_key.rb +13 -1
- data/lib/solid_redis/cluster/key_slot.rb +21 -3
- data/lib/solid_redis/cluster_client.rb +16 -4
- data/lib/solid_redis/cluster_state.rb +12 -9
- data/lib/solid_redis/version.rb +1 -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: c08bed5af20e5c6c0facedfd545397d0a9309e023188e9834ae27b27a916a4a4
|
|
4
|
+
data.tar.gz: 62d8881647d63bc677b371617c4ab45f3415a2817c3d7a7ebf05b71bbc9dcbd1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d21acc2027b48d9b107a390697dbd3b03df222b56850d2698013688f1f6f687c2a86fb88e55d20a1f25bbf215cd037d4b0bf7615d768e1b3999c2953d9f9ec4
|
|
7
|
+
data.tar.gz: 35da0e825cba8ea9464cc77dba1e072b9b25152484df91038a591d5b6e1277b80f51bc6b6c74ac60199da020d4a061071c15450b94c0b31de92223e75ce19c33
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to this project are documented in this file. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
|
|
5
5
|
project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [1.0.10] - 2026-09-30
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Require `solid-resp-ractor` 0.1.3 for lower-allocation command encoding,
|
|
12
|
+
response parsing, and socket readiness waits.
|
|
13
|
+
- Remove transient allocations from Cluster command normalization and CRC16
|
|
14
|
+
slot calculation.
|
|
15
|
+
- Cache Cluster state and bounded key-to-slot lookups, store configurations
|
|
16
|
+
directly in the slot table, and avoid locking stable slot reads.
|
|
17
|
+
- Improve Cluster throughput by 2.0% to 4.3% over `redis-cluster-client`
|
|
18
|
+
across 1, 2, and 4 Ractors in the six-run benchmark, with approximately 41%
|
|
19
|
+
fewer allocations per operation.
|
|
20
|
+
|
|
7
21
|
## [1.0.9] - 2026-09-29
|
|
8
22
|
|
|
9
23
|
### Changed
|
|
@@ -154,6 +168,7 @@ project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
154
168
|
TLS, reconnection), `Pool` owned by a single Ractor, pipelines, and
|
|
155
169
|
lifecycle callbacks via `callback-collection`.
|
|
156
170
|
|
|
171
|
+
[1.0.10]: https://github.com/nicolasva/solid-redis/compare/v1.0.9...v1.0.10
|
|
157
172
|
[1.0.9]: https://github.com/nicolasva/solid-redis/compare/v1.0.8...v1.0.9
|
|
158
173
|
[1.0.8]: https://github.com/nicolasva/solid-redis/compare/v1.0.7...v1.0.8
|
|
159
174
|
[1.0.7]: https://github.com/nicolasva/solid-redis/compare/v1.0.6...v1.0.7
|
data/README.md
CHANGED
|
@@ -592,7 +592,11 @@ Cluster rows compare `solid-redis` with `redis-cluster-client`, the
|
|
|
592
592
|
Cluster implementation built on `redis-client`. Unsupported combinations
|
|
593
593
|
are reported rather than replaced with a different concurrency model.
|
|
594
594
|
|
|
595
|
-
**Environment:** Ruby
|
|
595
|
+
**Environment:** Ruby 4.0.1 (arm64-darwin25); solid-redis 1.0.9; Redis server v=8.10.0 sha=00000000:1 malloc=libc bits=64 build=80fd3081013fc32b; redis-client 0.30.1; redis-cluster-client 0.17.1; Apple M2 Max, 12 logical CPUs, 96 GiB RAM, macOS 26.6.2.
|
|
596
|
+
|
|
597
|
+
GET/SET and Cluster rows for 1, 2, and 4 Ractors were refreshed from the
|
|
598
|
+
current checkout with the unreleased routing and RESP buffer optimizations.
|
|
599
|
+
The remaining rows come from the preceding full-matrix run.
|
|
596
600
|
|
|
597
601
|
Each row is measured in a fresh Ruby process. Both clients use RESP2,
|
|
598
602
|
identical commands and the same local Redis topology. Client order is
|
|
@@ -617,87 +621,76 @@ harness used for both clients, so they are comparative rather than
|
|
|
617
621
|
intrinsic library-only costs. `redis-cluster-client` uses its default
|
|
618
622
|
synchronous routing model (`concurrency: { model: :none }`).
|
|
619
623
|
|
|
620
|
-
|
|
621
|
-
From a checkout where both repositories are siblings, run the full matrix
|
|
622
|
-
(requires `redis-server` and `redis-cli`) with:
|
|
623
|
-
|
|
624
|
-
```sh
|
|
625
|
-
cd ../bench_mark_redis
|
|
626
|
-
SOLID_REDIS_PATH=../solid-redis bundle install
|
|
627
|
-
bundle exec rake comparison
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
To regenerate this README's benchmark tables:
|
|
624
|
+
Reproduce the full run (requires `redis-server` and `redis-cli`):
|
|
631
625
|
|
|
632
626
|
```sh
|
|
633
|
-
|
|
634
|
-
BENCHMARK_README=../solid-redis/README.md bundle exec rake comparison
|
|
627
|
+
BENCHMARK_README=README.md bundle exec rake benchmark:comparison
|
|
635
628
|
```
|
|
636
629
|
|
|
637
630
|
### GET / SET
|
|
638
631
|
|
|
639
632
|
| Ractors | Client | Throughput (ops/s) | p50 (ms) | p95 (ms) | p99 (ms) | CPU | Peak RSS | Allocations/op | Errors/run |
|
|
640
633
|
|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
641
|
-
| 1 | `redis-client` | 35,
|
|
642
|
-
| 1 | `solid-redis` |
|
|
643
|
-
| 2 | `redis-client` |
|
|
644
|
-
| 2 | `solid-redis` |
|
|
645
|
-
| 4 | `redis-client` |
|
|
646
|
-
| 4 | `solid-redis` |
|
|
647
|
-
| 8 | `redis-client` |
|
|
648
|
-
| 8 | `solid-redis` |
|
|
634
|
+
| 1 | `redis-client` | 35,899 | 0.028 | 0.036 | 0.047 | 57.8% | 42.5 MiB | 17.4 | 0 |
|
|
635
|
+
| 1 | `solid-redis` | 38,329 | 0.025 | 0.035 | 0.045 | 66.7% | 117.1 MiB | 10.4 | 0 |
|
|
636
|
+
| 2 | `redis-client` | 57,092 | 0.034 | 0.047 | 0.060 | 105.0% | 42.7 MiB | 17.4 | 0 |
|
|
637
|
+
| 2 | `solid-redis` | 59,489 | 0.032 | 0.047 | 0.059 | 115.9% | 131.1 MiB | 10.4 | 0 |
|
|
638
|
+
| 4 | `redis-client` | 83,927 | 0.046 | 0.068 | 0.098 | 198.4% | 42.8 MiB | 17.4 | 0 |
|
|
639
|
+
| 4 | `solid-redis` | 83,164 | 0.046 | 0.068 | 0.094 | 211.6% | 130.5 MiB | 10.4 | 0 |
|
|
640
|
+
| 8 | `redis-client` | 105,129 | 0.069 | 0.119 | 0.213 | 360.8% | 41.3 MiB | 17.4 | 0 |
|
|
641
|
+
| 8 | `solid-redis` | 99,759 | 0.070 | 0.128 | 0.267 | 378.0% | 97.7 MiB | 19.8 | 0 |
|
|
649
642
|
|
|
650
643
|
### Pipelines
|
|
651
644
|
|
|
652
645
|
| Ractors | Client | Throughput (ops/s) | p50 (ms) | p95 (ms) | p99 (ms) | CPU | Peak RSS | Allocations/op | Errors/run |
|
|
653
646
|
|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
654
|
-
| 1 | `redis-client` |
|
|
655
|
-
| 1 | `solid-redis` |
|
|
656
|
-
| 2 | `redis-client` |
|
|
657
|
-
| 2 | `solid-redis` |
|
|
658
|
-
| 4 | `redis-client` |
|
|
659
|
-
| 4 | `solid-redis` |
|
|
660
|
-
| 8 | `redis-client` |
|
|
661
|
-
| 8 | `solid-redis` |
|
|
647
|
+
| 1 | `redis-client` | 299,646 | 0.003 | 0.004 | 0.009 | 78.8% | 39.5 MiB | 12.6 | 0 |
|
|
648
|
+
| 1 | `solid-redis` | 300,831 | 0.003 | 0.004 | 0.007 | 79.4% | 41.0 MiB | 12.2 | 0 |
|
|
649
|
+
| 2 | `redis-client` | 537,360 | 0.003 | 0.005 | 0.011 | 150.3% | 40.9 MiB | 12.6 | 0 |
|
|
650
|
+
| 2 | `solid-redis` | 529,852 | 0.003 | 0.006 | 0.009 | 146.8% | 42.3 MiB | 12.2 | 0 |
|
|
651
|
+
| 4 | `redis-client` | 881,833 | 0.004 | 0.008 | 0.017 | 258.4% | 43.0 MiB | 12.6 | 0 |
|
|
652
|
+
| 4 | `solid-redis` | 873,375 | 0.004 | 0.010 | 0.017 | 255.5% | 46.8 MiB | 12.2 | 0 |
|
|
653
|
+
| 8 | `redis-client` | 1,115,081 | 0.006 | 0.015 | 0.020 | 389.3% | 42.3 MiB | 12.6 | 0 |
|
|
654
|
+
| 8 | `solid-redis` | 1,232,285 | 0.005 | 0.018 | 0.031 | 401.1% | 55.8 MiB | 12.2 | 0 |
|
|
662
655
|
|
|
663
656
|
### Isolated pool per Ractor
|
|
664
657
|
|
|
665
658
|
| Ractors | Client | Throughput (ops/s) | p50 (ms) | p95 (ms) | p99 (ms) | CPU | Peak RSS | Allocations/op | Errors/run |
|
|
666
659
|
|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
667
|
-
| 1 | `redis-client` | unsupported: Ractor
|
|
668
|
-
| 1 | `solid-redis` |
|
|
669
|
-
| 2 | `redis-client` | unsupported: Ractor
|
|
670
|
-
| 2 | `solid-redis` |
|
|
671
|
-
| 4 | `redis-client` | unsupported: Ractor
|
|
672
|
-
| 4 | `solid-redis` |
|
|
673
|
-
| 8 | `redis-client` | unsupported: Ractor
|
|
674
|
-
| 8 | `solid-redis` |
|
|
660
|
+
| 1 | `redis-client` | unsupported: Ractor isolation error (`connection_pool` uses non-shareable global state) | — | — | — | — | — | — | — |
|
|
661
|
+
| 1 | `solid-redis` | 38,731 | 0.025 | 0.031 | 0.039 | 69.2% | 71.1 MiB | 17.0 | 0 |
|
|
662
|
+
| 2 | `redis-client` | unsupported: Ractor isolation error (`connection_pool` uses non-shareable global state) | — | — | — | — | — | — | — |
|
|
663
|
+
| 2 | `solid-redis` | 64,181 | 0.029 | 0.044 | 0.060 | 123.5% | 83.3 MiB | 17.0 | 0 |
|
|
664
|
+
| 4 | `redis-client` | unsupported: Ractor isolation error (`connection_pool` uses non-shareable global state) | — | — | — | — | — | — | — |
|
|
665
|
+
| 4 | `solid-redis` | 83,755 | 0.045 | 0.067 | 0.100 | 214.4% | 87.3 MiB | 16.9 | 0 |
|
|
666
|
+
| 8 | `redis-client` | unsupported: Ractor isolation error (`connection_pool` uses non-shareable global state) | — | — | — | — | — | — | — |
|
|
667
|
+
| 8 | `solid-redis` | 108,840 | 0.067 | 0.110 | 0.220 | 400.3% | 110.1 MiB | 16.9 | 0 |
|
|
675
668
|
|
|
676
669
|
### Cluster
|
|
677
670
|
|
|
678
671
|
| Ractors | Client | Throughput (ops/s) | p50 (ms) | p95 (ms) | p99 (ms) | CPU | Peak RSS | Allocations/op | Errors/run |
|
|
679
672
|
|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
680
|
-
| 1 | `redis-client` |
|
|
681
|
-
| 1 | `solid-redis` |
|
|
682
|
-
| 2 | `redis-client` |
|
|
683
|
-
| 2 | `solid-redis` |
|
|
684
|
-
| 4 | `redis-client` |
|
|
685
|
-
| 4 | `solid-redis` |
|
|
686
|
-
| 8 | `redis-client` |
|
|
687
|
-
| 8 | `solid-redis` |
|
|
673
|
+
| 1 | `redis-client` | 29,459 | 0.033 | 0.042 | 0.057 | 62.4% | 42.6 MiB | 19.4 | 0 |
|
|
674
|
+
| 1 | `solid-redis` | 30,041 | 0.033 | 0.040 | 0.053 | 59.8% | 116.4 MiB | 11.4 | 0 |
|
|
675
|
+
| 2 | `redis-client` | 51,845 | 0.037 | 0.052 | 0.070 | 115.1% | 42.8 MiB | 19.4 | 0 |
|
|
676
|
+
| 2 | `solid-redis` | 54,065 | 0.035 | 0.050 | 0.063 | 115.4% | 126.3 MiB | 11.4 | 0 |
|
|
677
|
+
| 4 | `redis-client` | 76,652 | 0.051 | 0.070 | 0.097 | 217.3% | 47.6 MiB | 19.4 | 0 |
|
|
678
|
+
| 4 | `solid-redis` | 78,763 | 0.049 | 0.069 | 0.091 | 220.1% | 128.5 MiB | 11.4 | 0 |
|
|
679
|
+
| 8 | `redis-client` | 108,022 | 0.069 | 0.109 | 0.156 | 420.5% | 49.1 MiB | 19.4 | 0 |
|
|
680
|
+
| 8 | `solid-redis` | 98,677 | 0.072 | 0.127 | 0.302 | 433.3% | 86.9 MiB | 24.8 | 0 |
|
|
688
681
|
|
|
689
682
|
### Sentinel master crash
|
|
690
683
|
|
|
691
684
|
| Ractors | Client | Throughput (ops/s) | p50 (ms) | p95 (ms) | p99 (ms) | Recovery p50 (ms) | Recovery max (ms) | CPU | Peak RSS | Allocations/op | Errors/run |
|
|
692
685
|
|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
693
|
-
| 1 | `redis-client` |
|
|
694
|
-
| 1 | `solid-redis` | 32,
|
|
695
|
-
| 2 | `redis-client` |
|
|
696
|
-
| 2 | `solid-redis` | 50,
|
|
697
|
-
| 4 | `redis-client` |
|
|
698
|
-
| 4 | `solid-redis` |
|
|
699
|
-
| 8 | `redis-client` |
|
|
700
|
-
| 8 | `solid-redis` |
|
|
686
|
+
| 1 | `redis-client` | 30,243 | 0.027 | 0.036 | 0.048 | 1345.8 | 1345.8 | 50.5% | 42.3 MiB | 17.6 | 110 |
|
|
687
|
+
| 1 | `solid-redis` | 32,634 | 0.027 | 0.035 | 0.047 | 1284.6 | 1284.6 | 57.9% | 75.6 MiB | 20.1 | 105 |
|
|
688
|
+
| 2 | `redis-client` | 49,096 | 0.034 | 0.048 | 0.059 | 1279.1 | 1279.2 | 92.7% | 42.8 MiB | 17.6 | 205 |
|
|
689
|
+
| 2 | `solid-redis` | 50,166 | 0.033 | 0.047 | 0.062 | 1304.0 | 1304.0 | 100.7% | 85.6 MiB | 20.1 | 210 |
|
|
690
|
+
| 4 | `redis-client` | 72,364 | 0.046 | 0.068 | 0.100 | 1325.0 | 1325.1 | 174.7% | 43.3 MiB | 17.6 | 412 |
|
|
691
|
+
| 4 | `solid-redis` | 70,426 | 0.047 | 0.069 | 0.132 | 1336.2 | 1336.2 | 183.8% | 85.9 MiB | 20.2 | 416 |
|
|
692
|
+
| 8 | `redis-client` | 92,438 | 0.069 | 0.119 | 0.200 | 1332.8 | 1332.9 | 325.3% | 45.5 MiB | 17.7 | 772 |
|
|
693
|
+
| 8 | `solid-redis` | 87,879 | 0.070 | 0.132 | 0.247 | 1317.2 | 1317.6 | 342.4% | 84.3 MiB | 20.3 | 760 |
|
|
701
694
|
<!-- benchmark-results:end -->
|
|
702
695
|
|
|
703
696
|
## Development
|
|
@@ -28,7 +28,7 @@ module SolidRedis
|
|
|
28
28
|
|
|
29
29
|
# Returns the first key of +command+, or nil for keyless commands.
|
|
30
30
|
def for(command)
|
|
31
|
-
name = command[0]
|
|
31
|
+
name = normalize_name(command[0])
|
|
32
32
|
return if KEYLESS[name]
|
|
33
33
|
|
|
34
34
|
if (index = NUMKEYS_AT[name])
|
|
@@ -48,6 +48,18 @@ module SolidRedis
|
|
|
48
48
|
else command[1]
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
|
+
|
|
52
|
+
def normalize_name(value)
|
|
53
|
+
name = value.to_s
|
|
54
|
+
index = 0
|
|
55
|
+
while index < name.bytesize
|
|
56
|
+
byte = name.getbyte(index)
|
|
57
|
+
return name.upcase if byte >= 97 && byte <= 122
|
|
58
|
+
|
|
59
|
+
index += 1
|
|
60
|
+
end
|
|
61
|
+
name
|
|
62
|
+
end
|
|
51
63
|
end
|
|
52
64
|
end
|
|
53
65
|
end
|
|
@@ -19,7 +19,17 @@ module SolidRedis
|
|
|
19
19
|
module_function
|
|
20
20
|
|
|
21
21
|
def for(key)
|
|
22
|
-
|
|
22
|
+
string = key.to_s
|
|
23
|
+
first = 0
|
|
24
|
+
last = string.bytesize
|
|
25
|
+
if (open = string.index("{")) &&
|
|
26
|
+
(close = string.index("}", open + 1)) &&
|
|
27
|
+
close > open + 1
|
|
28
|
+
first = open + 1
|
|
29
|
+
last = close
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
crc16_range(string, first, last) % SLOTS
|
|
23
33
|
end
|
|
24
34
|
|
|
25
35
|
def hash_tag(key)
|
|
@@ -33,9 +43,17 @@ module SolidRedis
|
|
|
33
43
|
end
|
|
34
44
|
|
|
35
45
|
def crc16(string)
|
|
36
|
-
string
|
|
37
|
-
|
|
46
|
+
crc16_range(string, 0, string.bytesize)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def crc16_range(string, first, last)
|
|
50
|
+
crc = 0
|
|
51
|
+
while first < last
|
|
52
|
+
byte = string.getbyte(first)
|
|
53
|
+
crc = ((crc << 8) & 0xFFFF) ^ TABLE[((crc >> 8) ^ byte) & 0xFF]
|
|
54
|
+
first += 1
|
|
38
55
|
end
|
|
56
|
+
crc
|
|
39
57
|
end
|
|
40
58
|
end
|
|
41
59
|
end
|
|
@@ -7,6 +7,7 @@ module SolidRedis
|
|
|
7
7
|
class ClusterClient
|
|
8
8
|
REDIRECTION = /\A(MOVED|ASK) (\d+) (\S+):(\d+)\z/
|
|
9
9
|
RETRY_DELAY = 0.05
|
|
10
|
+
SLOT_CACHE_LIMIT = 1_024
|
|
10
11
|
TRANSIENT_ERRORS = %w[TRYAGAIN CLUSTERDOWN].freeze
|
|
11
12
|
|
|
12
13
|
attr_reader :config
|
|
@@ -15,6 +16,8 @@ module SolidRedis
|
|
|
15
16
|
@config = config
|
|
16
17
|
@name = name
|
|
17
18
|
@clients = {}
|
|
19
|
+
@slot_cache = {}
|
|
20
|
+
@state = config.state
|
|
18
21
|
end
|
|
19
22
|
|
|
20
23
|
def call(*command)
|
|
@@ -104,14 +107,14 @@ module SolidRedis
|
|
|
104
107
|
host = redirection[3]
|
|
105
108
|
port = Integer(redirection[4])
|
|
106
109
|
asking = redirection[1] == "ASK"
|
|
107
|
-
node = asking ?
|
|
110
|
+
node = asking ? @state.node(host, port) : @state.move(slot, host, port)
|
|
108
111
|
elsif error.message.start_with?("TRYAGAIN", "CLUSTERDOWN")
|
|
109
112
|
redirections += 1
|
|
110
113
|
raise FailoverError, "Cluster unavailable: #{error.message}" if redirections > config.max_redirections
|
|
111
114
|
|
|
112
115
|
asking = false
|
|
113
116
|
sleep RETRY_DELAY
|
|
114
|
-
|
|
117
|
+
@state.refresh
|
|
115
118
|
node = node_for(command)
|
|
116
119
|
else
|
|
117
120
|
raise
|
|
@@ -122,14 +125,23 @@ module SolidRedis
|
|
|
122
125
|
|
|
123
126
|
attempts += 1
|
|
124
127
|
config.notify(:connection_error, error.class.name, error.message)
|
|
125
|
-
|
|
128
|
+
@state.refresh
|
|
126
129
|
node = node_for(command)
|
|
127
130
|
end
|
|
128
131
|
end
|
|
129
132
|
|
|
130
133
|
def node_for(command)
|
|
131
134
|
key = Cluster::CommandKey.for(command)
|
|
132
|
-
|
|
135
|
+
return @state.any_node unless key
|
|
136
|
+
|
|
137
|
+
slot = @slot_cache[key]
|
|
138
|
+
unless slot
|
|
139
|
+
slot = Cluster::KeySlot.for(key)
|
|
140
|
+
@slot_cache.clear if @slot_cache.length >= SLOT_CACHE_LIMIT
|
|
141
|
+
cached_key = key.is_a?(String) && !key.frozen? ? key.dup.freeze : key
|
|
142
|
+
@slot_cache[cached_key] = slot
|
|
143
|
+
end
|
|
144
|
+
@state.node_for_slot(slot)
|
|
133
145
|
end
|
|
134
146
|
|
|
135
147
|
def transient_error?(error)
|
|
@@ -19,14 +19,17 @@ module SolidRedis
|
|
|
19
19
|
# Returns the master Config owning +slot+, discovering the topology when
|
|
20
20
|
# it is not known yet.
|
|
21
21
|
def node_for_slot(slot)
|
|
22
|
+
node = @slots[slot]
|
|
23
|
+
return node if node
|
|
24
|
+
|
|
22
25
|
@mutex.synchronize do
|
|
23
26
|
discover unless @discovered
|
|
24
|
-
|
|
25
|
-
if
|
|
27
|
+
node = @slots[slot]
|
|
28
|
+
if node.nil?
|
|
26
29
|
discover
|
|
27
|
-
|
|
30
|
+
node = @slots[slot]
|
|
28
31
|
end
|
|
29
|
-
|
|
32
|
+
node || raise(ConnectionError, "No cluster node serves slot #{slot}")
|
|
30
33
|
end
|
|
31
34
|
end
|
|
32
35
|
|
|
@@ -45,9 +48,9 @@ module SolidRedis
|
|
|
45
48
|
def move(slot, host, port)
|
|
46
49
|
@mutex.synchronize do
|
|
47
50
|
key = node_key(host, port)
|
|
48
|
-
@nodes[key] ||= node_config(host, port)
|
|
49
|
-
@slots[slot] =
|
|
50
|
-
|
|
51
|
+
node = @nodes[key] ||= node_config(host, port)
|
|
52
|
+
@slots[slot] = node
|
|
53
|
+
node
|
|
51
54
|
end
|
|
52
55
|
end
|
|
53
56
|
|
|
@@ -83,8 +86,8 @@ module SolidRedis
|
|
|
83
86
|
@nodes.clear
|
|
84
87
|
result.result[:ranges].each do |range|
|
|
85
88
|
key = node_key(range[:master][:host], range[:master][:port])
|
|
86
|
-
@nodes[key] ||= node_config(range[:master][:host], range[:master][:port])
|
|
87
|
-
(range[:from]..range[:to]).each { |slot| @slots[slot] =
|
|
89
|
+
node = @nodes[key] ||= node_config(range[:master][:host], range[:master][:port])
|
|
90
|
+
(range[:from]..range[:to]).each { |slot| @slots[slot] = node }
|
|
88
91
|
end
|
|
89
92
|
@discovered = true
|
|
90
93
|
@specification.notify(:resolved, "cluster", @nodes.keys.join(","))
|
data/lib/solid_redis/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solid-redis
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nicolas Vandenbogaerde
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0.1.
|
|
46
|
+
version: 0.1.3
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 0.1.
|
|
53
|
+
version: 0.1.3
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: minitest
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -118,7 +118,7 @@ licenses:
|
|
|
118
118
|
- MIT
|
|
119
119
|
metadata:
|
|
120
120
|
rubygems_mfa_required: 'true'
|
|
121
|
-
documentation_uri: https://www.rubydoc.info/gems/solid-redis/1.0.
|
|
121
|
+
documentation_uri: https://www.rubydoc.info/gems/solid-redis/1.0.10
|
|
122
122
|
source_code_uri: https://github.com/nicolasva/solid-redis
|
|
123
123
|
changelog_uri: https://github.com/nicolasva/solid-redis/blob/main/CHANGELOG.md
|
|
124
124
|
rdoc_options: []
|