You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					195 lines
				
				7.9 KiB
			
		
		
			
		
	
	
					195 lines
				
				7.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"use strict";
							 | 
						||
| 
								 | 
							
								Object.defineProperty(exports, "__esModule", { value: true });
							 | 
						||
| 
								 | 
							
								exports.ReadPreference = exports.ReadPreferenceMode = void 0;
							 | 
						||
| 
								 | 
							
								const error_1 = require("./error");
							 | 
						||
| 
								 | 
							
								/** @public */
							 | 
						||
| 
								 | 
							
								exports.ReadPreferenceMode = Object.freeze({
							 | 
						||
| 
								 | 
							
								    primary: 'primary',
							 | 
						||
| 
								 | 
							
								    primaryPreferred: 'primaryPreferred',
							 | 
						||
| 
								 | 
							
								    secondary: 'secondary',
							 | 
						||
| 
								 | 
							
								    secondaryPreferred: 'secondaryPreferred',
							 | 
						||
| 
								 | 
							
								    nearest: 'nearest'
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * The **ReadPreference** class is a class that represents a MongoDB ReadPreference and is
							 | 
						||
| 
								 | 
							
								 * used to construct connections.
							 | 
						||
| 
								 | 
							
								 * @public
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @see https://docs.mongodb.com/manual/core/read-preference/
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class ReadPreference {
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @param mode - A string describing the read preference mode (primary|primaryPreferred|secondary|secondaryPreferred|nearest)
							 | 
						||
| 
								 | 
							
								     * @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.
							 | 
						||
| 
								 | 
							
								     * @param options - Additional read preference options
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    constructor(mode, tags, options) {
							 | 
						||
| 
								 | 
							
								        if (!ReadPreference.isValid(mode)) {
							 | 
						||
| 
								 | 
							
								            throw new error_1.MongoInvalidArgumentError(`Invalid read preference mode ${JSON.stringify(mode)}`);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (options == null && typeof tags === 'object' && !Array.isArray(tags)) {
							 | 
						||
| 
								 | 
							
								            options = tags;
							 | 
						||
| 
								 | 
							
								            tags = undefined;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (tags && !Array.isArray(tags)) {
							 | 
						||
| 
								 | 
							
								            throw new error_1.MongoInvalidArgumentError('ReadPreference tags must be an array');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        this.mode = mode;
							 | 
						||
| 
								 | 
							
								        this.tags = tags;
							 | 
						||
| 
								 | 
							
								        this.hedge = options?.hedge;
							 | 
						||
| 
								 | 
							
								        this.maxStalenessSeconds = undefined;
							 | 
						||
| 
								 | 
							
								        this.minWireVersion = undefined;
							 | 
						||
| 
								 | 
							
								        options = options ?? {};
							 | 
						||
| 
								 | 
							
								        if (options.maxStalenessSeconds != null) {
							 | 
						||
| 
								 | 
							
								            if (options.maxStalenessSeconds <= 0) {
							 | 
						||
| 
								 | 
							
								                throw new error_1.MongoInvalidArgumentError('maxStalenessSeconds must be a positive integer');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            this.maxStalenessSeconds = options.maxStalenessSeconds;
							 | 
						||
| 
								 | 
							
								            // NOTE: The minimum required wire version is 5 for this read preference. If the existing
							 | 
						||
| 
								 | 
							
								            //       topology has a lower value then a MongoError will be thrown during server selection.
							 | 
						||
| 
								 | 
							
								            this.minWireVersion = 5;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (this.mode === ReadPreference.PRIMARY) {
							 | 
						||
| 
								 | 
							
								            if (this.tags && Array.isArray(this.tags) && this.tags.length > 0) {
							 | 
						||
| 
								 | 
							
								                throw new error_1.MongoInvalidArgumentError('Primary read preference cannot be combined with tags');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (this.maxStalenessSeconds) {
							 | 
						||
| 
								 | 
							
								                throw new error_1.MongoInvalidArgumentError('Primary read preference cannot be combined with maxStalenessSeconds');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (this.hedge) {
							 | 
						||
| 
								 | 
							
								                throw new error_1.MongoInvalidArgumentError('Primary read preference cannot be combined with hedge');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // Support the deprecated `preference` property introduced in the porcelain layer
							 | 
						||
| 
								 | 
							
								    get preference() {
							 | 
						||
| 
								 | 
							
								        return this.mode;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    static fromString(mode) {
							 | 
						||
| 
								 | 
							
								        return new ReadPreference(mode);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Construct a ReadPreference given an options object.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param options - The options object from which to extract the read preference.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    static fromOptions(options) {
							 | 
						||
| 
								 | 
							
								        if (!options)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								        const readPreference = options.readPreference ?? options.session?.transaction.options.readPreference;
							 | 
						||
| 
								 | 
							
								        const readPreferenceTags = options.readPreferenceTags;
							 | 
						||
| 
								 | 
							
								        if (readPreference == null) {
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (typeof readPreference === 'string') {
							 | 
						||
| 
								 | 
							
								            return new ReadPreference(readPreference, readPreferenceTags, {
							 | 
						||
| 
								 | 
							
								                maxStalenessSeconds: options.maxStalenessSeconds,
							 | 
						||
| 
								 | 
							
								                hedge: options.hedge
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (!(readPreference instanceof ReadPreference) && typeof readPreference === 'object') {
							 | 
						||
| 
								 | 
							
								            const mode = readPreference.mode || readPreference.preference;
							 | 
						||
| 
								 | 
							
								            if (mode && typeof mode === 'string') {
							 | 
						||
| 
								 | 
							
								                return new ReadPreference(mode, readPreference.tags ?? readPreferenceTags, {
							 | 
						||
| 
								 | 
							
								                    maxStalenessSeconds: readPreference.maxStalenessSeconds,
							 | 
						||
| 
								 | 
							
								                    hedge: options.hedge
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (readPreferenceTags) {
							 | 
						||
| 
								 | 
							
								            readPreference.tags = readPreferenceTags;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return readPreference;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Replaces options.readPreference with a ReadPreference instance
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    static translate(options) {
							 | 
						||
| 
								 | 
							
								        if (options.readPreference == null)
							 | 
						||
| 
								 | 
							
								            return options;
							 | 
						||
| 
								 | 
							
								        const r = options.readPreference;
							 | 
						||
| 
								 | 
							
								        if (typeof r === 'string') {
							 | 
						||
| 
								 | 
							
								            options.readPreference = new ReadPreference(r);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (r && !(r instanceof ReadPreference) && typeof r === 'object') {
							 | 
						||
| 
								 | 
							
								            const mode = r.mode || r.preference;
							 | 
						||
| 
								 | 
							
								            if (mode && typeof mode === 'string') {
							 | 
						||
| 
								 | 
							
								                options.readPreference = new ReadPreference(mode, r.tags, {
							 | 
						||
| 
								 | 
							
								                    maxStalenessSeconds: r.maxStalenessSeconds
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (!(r instanceof ReadPreference)) {
							 | 
						||
| 
								 | 
							
								            throw new error_1.MongoInvalidArgumentError(`Invalid read preference: ${r}`);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return options;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Validate if a mode is legal
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param mode - The string representing the read preference mode.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    static isValid(mode) {
							 | 
						||
| 
								 | 
							
								        const VALID_MODES = new Set([
							 | 
						||
| 
								 | 
							
								            ReadPreference.PRIMARY,
							 | 
						||
| 
								 | 
							
								            ReadPreference.PRIMARY_PREFERRED,
							 | 
						||
| 
								 | 
							
								            ReadPreference.SECONDARY,
							 | 
						||
| 
								 | 
							
								            ReadPreference.SECONDARY_PREFERRED,
							 | 
						||
| 
								 | 
							
								            ReadPreference.NEAREST,
							 | 
						||
| 
								 | 
							
								            null
							 | 
						||
| 
								 | 
							
								        ]);
							 | 
						||
| 
								 | 
							
								        return VALID_MODES.has(mode);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Validate if a mode is legal
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param mode - The string representing the read preference mode.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    isValid(mode) {
							 | 
						||
| 
								 | 
							
								        return ReadPreference.isValid(typeof mode === 'string' ? mode : this.mode);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Indicates that this readPreference needs the "SecondaryOk" bit when sent over the wire
							 | 
						||
| 
								 | 
							
								     * @see https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/#op-query
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    secondaryOk() {
							 | 
						||
| 
								 | 
							
								        const NEEDS_SECONDARYOK = new Set([
							 | 
						||
| 
								 | 
							
								            ReadPreference.PRIMARY_PREFERRED,
							 | 
						||
| 
								 | 
							
								            ReadPreference.SECONDARY,
							 | 
						||
| 
								 | 
							
								            ReadPreference.SECONDARY_PREFERRED,
							 | 
						||
| 
								 | 
							
								            ReadPreference.NEAREST
							 | 
						||
| 
								 | 
							
								        ]);
							 | 
						||
| 
								 | 
							
								        return NEEDS_SECONDARYOK.has(this.mode);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Check if the two ReadPreferences are equivalent
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param readPreference - The read preference with which to check equality
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    equals(readPreference) {
							 | 
						||
| 
								 | 
							
								        return readPreference.mode === this.mode;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /** Return JSON representation */
							 | 
						||
| 
								 | 
							
								    toJSON() {
							 | 
						||
| 
								 | 
							
								        const readPreference = { mode: this.mode };
							 | 
						||
| 
								 | 
							
								        if (Array.isArray(this.tags))
							 | 
						||
| 
								 | 
							
								            readPreference.tags = this.tags;
							 | 
						||
| 
								 | 
							
								        if (this.maxStalenessSeconds)
							 | 
						||
| 
								 | 
							
								            readPreference.maxStalenessSeconds = this.maxStalenessSeconds;
							 | 
						||
| 
								 | 
							
								        if (this.hedge)
							 | 
						||
| 
								 | 
							
								            readPreference.hedge = this.hedge;
							 | 
						||
| 
								 | 
							
								        return readPreference;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								exports.ReadPreference = ReadPreference;
							 | 
						||
| 
								 | 
							
								ReadPreference.PRIMARY = exports.ReadPreferenceMode.primary;
							 | 
						||
| 
								 | 
							
								ReadPreference.PRIMARY_PREFERRED = exports.ReadPreferenceMode.primaryPreferred;
							 | 
						||
| 
								 | 
							
								ReadPreference.SECONDARY = exports.ReadPreferenceMode.secondary;
							 | 
						||
| 
								 | 
							
								ReadPreference.SECONDARY_PREFERRED = exports.ReadPreferenceMode.secondaryPreferred;
							 | 
						||
| 
								 | 
							
								ReadPreference.NEAREST = exports.ReadPreferenceMode.nearest;
							 | 
						||
| 
								 | 
							
								ReadPreference.primary = new ReadPreference(exports.ReadPreferenceMode.primary);
							 | 
						||
| 
								 | 
							
								ReadPreference.primaryPreferred = new ReadPreference(exports.ReadPreferenceMode.primaryPreferred);
							 | 
						||
| 
								 | 
							
								ReadPreference.secondary = new ReadPreference(exports.ReadPreferenceMode.secondary);
							 | 
						||
| 
								 | 
							
								ReadPreference.secondaryPreferred = new ReadPreference(exports.ReadPreferenceMode.secondaryPreferred);
							 | 
						||
| 
								 | 
							
								ReadPreference.nearest = new ReadPreference(exports.ReadPreferenceMode.nearest);
							 | 
						||
| 
								 | 
							
								//# sourceMappingURL=read_preference.js.map
							 |