ioredis 4.22.0 → 4.23.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.
package/Changelog.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [4.23.0](https://github.com/luin/ioredis/compare/v4.22.0...v4.23.0) (2021-02-25)
2
+
3
+
4
+ ### Features
5
+
6
+ * add support for DNS SRV records ([#1283](https://github.com/luin/ioredis/issues/1283)) ([13a8614](https://github.com/luin/ioredis/commit/13a861432c2331ca25038f6b4eb060ba7b865b47))
7
+
1
8
  # [4.22.0](https://github.com/luin/ioredis/compare/v4.21.0...v4.22.0) (2021-02-06)
2
9
 
3
10
 
@@ -12,6 +12,8 @@ exports.DEFAULT_CLUSTER_OPTIONS = {
12
12
  retryDelayOnTryAgain: 100,
13
13
  slotsRefreshTimeout: 1000,
14
14
  slotsRefreshInterval: 5000,
15
+ useSRVRecords: false,
16
+ resolveSrv: dns_1.resolveSrv,
15
17
  dnsLookup: dns_1.lookup,
16
18
  enableAutoPipelining: false,
17
19
  autoPipeliningIgnoredCommands: [],
@@ -726,6 +726,30 @@ class Cluster extends events_1.EventEmitter {
726
726
  }
727
727
  });
728
728
  }
729
+ resolveSrv(hostname) {
730
+ return new Promise((resolve, reject) => {
731
+ this.options.resolveSrv(hostname, (err, records) => {
732
+ if (err) {
733
+ return reject(err);
734
+ }
735
+ const self = this, groupedRecords = util_1.groupSrvRecords(records), sortedKeys = Object.keys(groupedRecords).sort((a, b) => parseInt(a) - parseInt(b));
736
+ function tryFirstOne(err) {
737
+ if (!sortedKeys.length) {
738
+ return reject(err);
739
+ }
740
+ const key = sortedKeys[0], group = groupedRecords[key], record = util_1.weightSrvRecords(group);
741
+ if (!group.records.length) {
742
+ sortedKeys.shift();
743
+ }
744
+ self.dnsLookup(record.name).then((host) => resolve({
745
+ host,
746
+ port: record.port,
747
+ }), tryFirstOne);
748
+ }
749
+ tryFirstOne();
750
+ });
751
+ });
752
+ }
729
753
  dnsLookup(hostname) {
730
754
  return new Promise((resolve, reject) => {
731
755
  this.options.dnsLookup(hostname, (err, address) => {
@@ -758,11 +782,20 @@ class Cluster extends events_1.EventEmitter {
758
782
  if (hostnames.length === 0) {
759
783
  return Promise.resolve(startupNodes);
760
784
  }
761
- return Promise.all(hostnames.map((hostname) => this.dnsLookup(hostname))).then((ips) => {
762
- const hostnameToIP = utils_2.zipMap(hostnames, ips);
763
- return startupNodes.map((node) => hostnameToIP.has(node.host)
764
- ? Object.assign({}, node, { host: hostnameToIP.get(node.host) })
765
- : node);
785
+ return Promise.all(hostnames.map((this.options.useSRVRecords ? this.resolveSrv : this.dnsLookup).bind(this))).then((configs) => {
786
+ const hostnameToConfig = utils_2.zipMap(hostnames, configs);
787
+ return startupNodes.map((node) => {
788
+ const config = hostnameToConfig.get(node.host);
789
+ if (!config) {
790
+ return node;
791
+ }
792
+ else if (this.options.useSRVRecords) {
793
+ return Object.assign({}, node, config);
794
+ }
795
+ else {
796
+ return Object.assign({}, node, { host: config });
797
+ }
798
+ });
766
799
  });
767
800
  }
768
801
  }
@@ -57,3 +57,38 @@ function getUniqueHostnamesFromOptions(nodes) {
57
57
  return Object.keys(uniqueHostsMap).filter((host) => !net_1.isIP(host));
58
58
  }
59
59
  exports.getUniqueHostnamesFromOptions = getUniqueHostnamesFromOptions;
60
+ function groupSrvRecords(records) {
61
+ const recordsByPriority = {};
62
+ for (const record of records) {
63
+ if (!recordsByPriority.hasOwnProperty(record.priority)) {
64
+ recordsByPriority[record.priority] = {
65
+ totalWeight: record.weight,
66
+ records: [record],
67
+ };
68
+ }
69
+ else {
70
+ recordsByPriority[record.priority].totalWeight += record.weight;
71
+ recordsByPriority[record.priority].records.push(record);
72
+ }
73
+ }
74
+ return recordsByPriority;
75
+ }
76
+ exports.groupSrvRecords = groupSrvRecords;
77
+ function weightSrvRecords(recordsGroup) {
78
+ if (recordsGroup.records.length === 1) {
79
+ recordsGroup.totalWeight = 0;
80
+ return recordsGroup.records.shift();
81
+ }
82
+ // + `recordsGroup.records.length` to support `weight` 0
83
+ const random = Math.floor(Math.random() * (recordsGroup.totalWeight + recordsGroup.records.length));
84
+ let total = 0;
85
+ for (const [i, record] of recordsGroup.records.entries()) {
86
+ total += 1 + record.weight;
87
+ if (total > random) {
88
+ recordsGroup.totalWeight -= record.weight;
89
+ recordsGroup.records.splice(i, 1);
90
+ return record;
91
+ }
92
+ }
93
+ }
94
+ exports.weightSrvRecords = weightSrvRecords;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ioredis",
3
- "version": "4.22.0",
3
+ "version": "4.23.0",
4
4
  "description": "A robust, performance-focused and full-featured Redis client for Node.js.",
5
5
  "main": "built/index.js",
6
6
  "files": [