read_preference.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.ReadPreference = exports.ReadPreferenceMode = void 0;
  4. const error_1 = require("./error");
  5. /** @public */
  6. exports.ReadPreferenceMode = Object.freeze({
  7. primary: 'primary',
  8. primaryPreferred: 'primaryPreferred',
  9. secondary: 'secondary',
  10. secondaryPreferred: 'secondaryPreferred',
  11. nearest: 'nearest'
  12. });
  13. /**
  14. * The **ReadPreference** class is a class that represents a MongoDB ReadPreference and is
  15. * used to construct connections.
  16. * @public
  17. *
  18. * @see https://www.mongodb.com/docs/manual/core/read-preference/
  19. */
  20. class ReadPreference {
  21. static { this.PRIMARY = exports.ReadPreferenceMode.primary; }
  22. static { this.PRIMARY_PREFERRED = exports.ReadPreferenceMode.primaryPreferred; }
  23. static { this.SECONDARY = exports.ReadPreferenceMode.secondary; }
  24. static { this.SECONDARY_PREFERRED = exports.ReadPreferenceMode.secondaryPreferred; }
  25. static { this.NEAREST = exports.ReadPreferenceMode.nearest; }
  26. static { this.primary = new ReadPreference(exports.ReadPreferenceMode.primary); }
  27. static { this.primaryPreferred = new ReadPreference(exports.ReadPreferenceMode.primaryPreferred); }
  28. static { this.secondary = new ReadPreference(exports.ReadPreferenceMode.secondary); }
  29. static { this.secondaryPreferred = new ReadPreference(exports.ReadPreferenceMode.secondaryPreferred); }
  30. static { this.nearest = new ReadPreference(exports.ReadPreferenceMode.nearest); }
  31. /**
  32. * @param mode - A string describing the read preference mode (primary|primaryPreferred|secondary|secondaryPreferred|nearest)
  33. * @param tags - A tag set used to target reads to members with the specified tag(s). tagSet is not available if using read preference mode primary.
  34. * @param options - Additional read preference options
  35. */
  36. constructor(mode, tags, options) {
  37. if (!ReadPreference.isValid(mode)) {
  38. throw new error_1.MongoInvalidArgumentError(`Invalid read preference mode ${JSON.stringify(mode)}`);
  39. }
  40. if (options == null && typeof tags === 'object' && !Array.isArray(tags)) {
  41. options = tags;
  42. tags = undefined;
  43. }
  44. else if (tags && !Array.isArray(tags)) {
  45. throw new error_1.MongoInvalidArgumentError('ReadPreference tags must be an array');
  46. }
  47. this.mode = mode;
  48. this.tags = tags;
  49. this.hedge = options?.hedge;
  50. this.maxStalenessSeconds = undefined;
  51. options = options ?? {};
  52. if (options.maxStalenessSeconds != null) {
  53. if (options.maxStalenessSeconds <= 0) {
  54. throw new error_1.MongoInvalidArgumentError('maxStalenessSeconds must be a positive integer');
  55. }
  56. this.maxStalenessSeconds = options.maxStalenessSeconds;
  57. }
  58. if (this.mode === ReadPreference.PRIMARY) {
  59. if (this.tags && Array.isArray(this.tags) && this.tags.length > 0) {
  60. throw new error_1.MongoInvalidArgumentError('Primary read preference cannot be combined with tags');
  61. }
  62. if (this.maxStalenessSeconds) {
  63. throw new error_1.MongoInvalidArgumentError('Primary read preference cannot be combined with maxStalenessSeconds');
  64. }
  65. if (this.hedge) {
  66. throw new error_1.MongoInvalidArgumentError('Primary read preference cannot be combined with hedge');
  67. }
  68. }
  69. }
  70. // Support the deprecated `preference` property introduced in the porcelain layer
  71. get preference() {
  72. return this.mode;
  73. }
  74. static fromString(mode) {
  75. return new ReadPreference(mode);
  76. }
  77. /**
  78. * Construct a ReadPreference given an options object.
  79. *
  80. * @param options - The options object from which to extract the read preference.
  81. */
  82. static fromOptions(options) {
  83. if (!options)
  84. return;
  85. const readPreference = options.readPreference ?? options.session?.transaction.options.readPreference;
  86. const readPreferenceTags = options.readPreferenceTags;
  87. if (readPreference == null) {
  88. return;
  89. }
  90. if (typeof readPreference === 'string') {
  91. return new ReadPreference(readPreference, readPreferenceTags, {
  92. maxStalenessSeconds: options.maxStalenessSeconds,
  93. hedge: options.hedge
  94. });
  95. }
  96. else if (!(readPreference instanceof ReadPreference) && typeof readPreference === 'object') {
  97. const mode = readPreference.mode || readPreference.preference;
  98. if (mode && typeof mode === 'string') {
  99. return new ReadPreference(mode, readPreference.tags ?? readPreferenceTags, {
  100. maxStalenessSeconds: readPreference.maxStalenessSeconds,
  101. hedge: options.hedge
  102. });
  103. }
  104. }
  105. if (readPreferenceTags) {
  106. readPreference.tags = readPreferenceTags;
  107. }
  108. return readPreference;
  109. }
  110. /**
  111. * Replaces options.readPreference with a ReadPreference instance
  112. */
  113. static translate(options) {
  114. if (options.readPreference == null)
  115. return options;
  116. const r = options.readPreference;
  117. if (typeof r === 'string') {
  118. options.readPreference = new ReadPreference(r);
  119. }
  120. else if (r && !(r instanceof ReadPreference) && typeof r === 'object') {
  121. const mode = r.mode || r.preference;
  122. if (mode && typeof mode === 'string') {
  123. options.readPreference = new ReadPreference(mode, r.tags, {
  124. maxStalenessSeconds: r.maxStalenessSeconds
  125. });
  126. }
  127. }
  128. else if (!(r instanceof ReadPreference)) {
  129. throw new error_1.MongoInvalidArgumentError(`Invalid read preference: ${r}`);
  130. }
  131. return options;
  132. }
  133. /**
  134. * Validate if a mode is legal
  135. *
  136. * @param mode - The string representing the read preference mode.
  137. */
  138. static isValid(mode) {
  139. const VALID_MODES = new Set([
  140. ReadPreference.PRIMARY,
  141. ReadPreference.PRIMARY_PREFERRED,
  142. ReadPreference.SECONDARY,
  143. ReadPreference.SECONDARY_PREFERRED,
  144. ReadPreference.NEAREST,
  145. null
  146. ]);
  147. return VALID_MODES.has(mode);
  148. }
  149. /**
  150. * Validate if a mode is legal
  151. *
  152. * @param mode - The string representing the read preference mode.
  153. */
  154. isValid(mode) {
  155. return ReadPreference.isValid(typeof mode === 'string' ? mode : this.mode);
  156. }
  157. /**
  158. * Indicates that this readPreference needs the "SecondaryOk" bit when sent over the wire
  159. * @see https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol/#op-query
  160. */
  161. secondaryOk() {
  162. const NEEDS_SECONDARYOK = new Set([
  163. ReadPreference.PRIMARY_PREFERRED,
  164. ReadPreference.SECONDARY,
  165. ReadPreference.SECONDARY_PREFERRED,
  166. ReadPreference.NEAREST
  167. ]);
  168. return NEEDS_SECONDARYOK.has(this.mode);
  169. }
  170. /**
  171. * Check if the two ReadPreferences are equivalent
  172. *
  173. * @param readPreference - The read preference with which to check equality
  174. */
  175. equals(readPreference) {
  176. return readPreference.mode === this.mode;
  177. }
  178. /** Return JSON representation */
  179. toJSON() {
  180. const readPreference = { mode: this.mode };
  181. if (Array.isArray(this.tags))
  182. readPreference.tags = this.tags;
  183. if (this.maxStalenessSeconds)
  184. readPreference.maxStalenessSeconds = this.maxStalenessSeconds;
  185. if (this.hedge)
  186. readPreference.hedge = this.hedge;
  187. return readPreference;
  188. }
  189. }
  190. exports.ReadPreference = ReadPreference;
  191. //# sourceMappingURL=read_preference.js.map