connector.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.Connector = exports.SequentialConnectionStrategy = exports.ParallelConnectionStrategy = void 0;
  6. var _net = _interopRequireDefault(require("net"));
  7. var _dns = _interopRequireDefault(require("dns"));
  8. var punycode = _interopRequireWildcard(require("punycode"));
  9. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
  10. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  12. class ParallelConnectionStrategy {
  13. constructor(addresses, options) {
  14. this.addresses = addresses;
  15. this.options = options;
  16. }
  17. connect(callback) {
  18. const addresses = this.addresses;
  19. const sockets = new Array(addresses.length);
  20. let errorCount = 0;
  21. function onError(_err) {
  22. errorCount += 1;
  23. this.removeListener('error', onError);
  24. this.removeListener('connect', onConnect);
  25. if (errorCount === addresses.length) {
  26. callback(new Error('Could not connect (parallel)'));
  27. }
  28. }
  29. function onConnect() {
  30. for (let j = 0; j < sockets.length; j++) {
  31. const socket = sockets[j];
  32. if (this === socket) {
  33. continue;
  34. }
  35. socket.removeListener('error', onError);
  36. socket.removeListener('connect', onConnect);
  37. socket.destroy();
  38. }
  39. callback(null, this);
  40. }
  41. for (let i = 0, len = addresses.length; i < len; i++) {
  42. const socket = sockets[i] = _net.default.connect(Object.create(this.options, {
  43. host: {
  44. value: addresses[i].address
  45. }
  46. }));
  47. socket.on('error', onError);
  48. socket.on('connect', onConnect);
  49. }
  50. }
  51. }
  52. exports.ParallelConnectionStrategy = ParallelConnectionStrategy;
  53. class SequentialConnectionStrategy {
  54. constructor(addresses, options) {
  55. this.addresses = addresses;
  56. this.options = options;
  57. }
  58. connect(callback) {
  59. const next = this.addresses.shift();
  60. if (!next) {
  61. return callback(new Error('Could not connect (sequence)'));
  62. }
  63. const socket = _net.default.connect(Object.create(this.options, {
  64. host: {
  65. value: next.address
  66. }
  67. }));
  68. const onError = _err => {
  69. socket.removeListener('error', onError);
  70. socket.removeListener('connect', onConnect);
  71. socket.destroy();
  72. this.connect(callback);
  73. };
  74. const onConnect = () => {
  75. socket.removeListener('error', onError);
  76. socket.removeListener('connect', onConnect);
  77. callback(null, socket);
  78. };
  79. socket.on('error', onError);
  80. socket.on('connect', onConnect);
  81. }
  82. }
  83. exports.SequentialConnectionStrategy = SequentialConnectionStrategy;
  84. class Connector {
  85. constructor(options, multiSubnetFailover) {
  86. this.options = options;
  87. this.multiSubnetFailover = multiSubnetFailover;
  88. }
  89. execute(cb) {
  90. if (_net.default.isIP(this.options.host)) {
  91. this.executeForIP(cb);
  92. } else {
  93. this.executeForHostname(cb);
  94. }
  95. }
  96. executeForIP(cb) {
  97. const socket = _net.default.connect(this.options);
  98. const onError = err => {
  99. socket.removeListener('error', onError);
  100. socket.removeListener('connect', onConnect);
  101. socket.destroy();
  102. cb(err);
  103. };
  104. const onConnect = () => {
  105. socket.removeListener('error', onError);
  106. socket.removeListener('connect', onConnect);
  107. cb(null, socket);
  108. };
  109. socket.on('error', onError);
  110. socket.on('connect', onConnect);
  111. }
  112. executeForHostname(cb) {
  113. _dns.default.lookup(punycode.toASCII(this.options.host), {
  114. all: true
  115. }, (err, addresses) => {
  116. if (err) {
  117. return cb(err);
  118. }
  119. if (this.multiSubnetFailover) {
  120. new ParallelConnectionStrategy(addresses, this.options).connect(cb);
  121. } else {
  122. new SequentialConnectionStrategy(addresses, this.options).connect(cb);
  123. }
  124. });
  125. }
  126. }
  127. exports.Connector = Connector;