Represents a pool of connections to a MongoDB server.
        // constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="MongoServerInstance"/> class.
        /// </summary>
        /// <param name="settings">The settings.</param>
        /// <param name="address">The address.</param>
        internal MongoServerInstance(MongoServerSettings settings, MongoServerAddress address)
        {
            _settings = settings;
            _address = address;
            _sequentialId = Interlocked.Increment(ref __nextSequentialId);
            _state = MongoServerState.Disconnected;
            _serverInfo = new ServerInformation
            {
                MaxDocumentSize = MongoDefaults.MaxDocumentSize,
                MaxMessageLength = MongoDefaults.MaxMessageLength,
                InstanceType = MongoServerInstanceType.Unknown
            };
            _connectionPool = new MongoConnectionPool(this);
            _pingTimeAggregator = new PingTimeAggregator(5);
            _permanentlyDisconnected = false;
            // Console.WriteLine("MongoServerInstance[{0}]: {1}", sequentialId, address);

            _stateVerificationAcquireConnectionOptions = new MongoConnectionPool.AcquireConnectionOptions
            {
                OkToAvoidWaitingByCreatingNewConnection = false,
                OkToExceedMaxConnectionPoolSize = true,
                OkToExceedWaitQueueSize = true,
                WaitQueueTimeout = TimeSpan.FromSeconds(2)
            };
        }
 // constructors
 internal MongoConnection(MongoConnectionPool connectionPool)
 {
     _serverInstance = connectionPool.ServerInstance;
     _connectionPool = connectionPool;
     _generationId   = connectionPool.GenerationId;
     _createdAt      = DateTime.UtcNow;
     _state          = MongoConnectionState.Initial;
 }
Example #3
0
 // constructors
 internal MongoConnection(MongoConnectionPool connectionPool)
 {
     this.serverInstance = connectionPool.ServerInstance;
     this.connectionPool = connectionPool;
     this.generationId   = connectionPool.GenerationId;
     this.createdAt      = DateTime.UtcNow;
     this.state          = MongoConnectionState.Initial;
 }
Example #4
0
 internal MongoConnection(
     MongoConnectionPool connectionPool,
     IPEndPoint endPoint
     )
 {
     this.connectionPool = connectionPool;
     this.endPoint       = endPoint;
     this.createdAt      = DateTime.UtcNow;
     this.state          = MongoConnectionState.Initial;
 }
        private MongoServerState _state; // always use property to set value so event gets raised

        // constructors
        internal MongoServerInstance(MongoServer server, MongoServerAddress address)
        {
            _server = server;
            _address = address;
            _sequentialId = Interlocked.Increment(ref __nextSequentialId);
            _maxDocumentSize = MongoDefaults.MaxDocumentSize;
            _maxMessageLength = MongoDefaults.MaxMessageLength;
            _state = MongoServerState.Disconnected;
            _connectionPool = new MongoConnectionPool(this);
            // Console.WriteLine("MongoServerInstance[{0}]: {1}", sequentialId, address);
        }
 // constructors
 internal MongoServerInstance(MongoServer server, MongoServerAddress address)
 {
     this.server = server;
     this.address = address;
     this.sequentialId = Interlocked.Increment(ref nextSequentialId);
     this.maxDocumentSize = MongoDefaults.MaxDocumentSize;
     this.maxMessageLength = MongoDefaults.MaxMessageLength;
     this.state = MongoServerState.Disconnected;
     this.connectionPool = new MongoConnectionPool(this);
     this.tags = new HashSet<string>();
     // Console.WriteLine("MongoServerInstance[{0}]: {1}", sequentialId, address);
 }
 // constructors
 /// <summary>
 /// Initializes a new instance of the <see cref="MongoServerInstance"/> class.
 /// </summary>
 /// <param name="settings">The settings.</param>
 /// <param name="address">The address.</param>
 internal MongoServerInstance(MongoServerSettings settings, MongoServerAddress address)
 {
     _settings = settings;
     _address = address;
     _sequentialId = Interlocked.Increment(ref __nextSequentialId);
     _state = MongoServerState.Disconnected;
     _serverInfo = new ServerInformation
     {
         MaxDocumentSize = MongoDefaults.MaxDocumentSize,
         MaxMessageLength = MongoDefaults.MaxMessageLength,
         InstanceType = MongoServerInstanceType.Unknown
     };
     _connectionPool = new MongoConnectionPool(this);
     _pingTimeAggregator = new PingTimeAggregator(5);
     _permanentlyDisconnected = false;
     // Console.WriteLine("MongoServerInstance[{0}]: {1}", sequentialId, address);
 }
Example #8
0
        // normally a connection is linked to a connection pool at the time it is created
        // but the very first connection was made by FindServer before the connection pool existed
        // we don't want to waste that connection so it becomes the first connection of the new connection pool
        internal void JoinConnectionPool(
            MongoConnectionPool connectionPool
            )
        {
            if (state == MongoConnectionState.Closed)
            {
                throw new InvalidOperationException("Connection is closed");
            }
            if (this.connectionPool != null)
            {
                throw new ArgumentException("The connection is already in a connection pool", "this");
            }
            if (connectionPool.EndPoint != endPoint)
            {
                throw new ArgumentException("A connection can only join a connection pool with the same IP address", "connectionPool");
            }

            this.connectionPool = connectionPool;
            this.lastUsedAt     = DateTime.UtcNow;
        }
 internal void Disconnect() {
     if (state != MongoServerState.Disconnected) {
         try {
             // if we fail during Connect the connectionPool field will still be null
             if (connectionPool != null) {
                 connectionPool.Close();
                 connectionPool = null;
             }
         } finally {
             State = MongoServerState.Disconnected;
         }
     }
 }
        internal void Connect(
            bool slaveOk
        ) {
            if (state != MongoServerState.Disconnected) {
                var message = string.Format("MongoServerInstance.Connect can only be called when state is Disconnected, not when state is {0}.", state);
                throw new InvalidOperationException(message);
            }

            State = MongoServerState.Connecting;
            connectException = null;
            try {
                endPoint = address.ToIPEndPoint(server.Settings.AddressFamily);

                var connectionPool = new MongoConnectionPool(this);
                try {
                    var connection = connectionPool.AcquireConnection(null);
                    try {
                        try {
                            var isMasterCommand = new CommandDocument("ismaster", 1);
                            isMasterResult = connection.RunCommand("admin.$cmd", QueryFlags.SlaveOk, isMasterCommand);
                        } catch (MongoCommandException ex) {
                            isMasterResult = ex.CommandResult;
                            throw;
                        }

                        isPrimary = isMasterResult.Response["ismaster", false].ToBoolean();
                        isSecondary = isMasterResult.Response["secondary", false].ToBoolean();
                        isPassive = isMasterResult.Response["passive", false].ToBoolean();
                        isArbiter = isMasterResult.Response["arbiterOnly", false].ToBoolean();
                        if (!isPrimary && !slaveOk) {
                            throw new MongoConnectionException("Server is not a primary and SlaveOk is false.");
                        }

                        maxDocumentSize = isMasterResult.Response["maxBsonObjectSize", MongoDefaults.MaxDocumentSize].ToInt32();
                        maxMessageLength = Math.Max(MongoDefaults.MaxMessageLength, maxDocumentSize + 1024); // derived from maxDocumentSize

                        var buildInfoCommand = new CommandDocument("buildinfo", 1);
                        var buildInfoResult = connection.RunCommand("admin.$cmd", QueryFlags.SlaveOk, buildInfoCommand);
                        buildInfo = new MongoServerBuildInfo(
                            buildInfoResult.Response["bits"].ToInt32(), // bits
                            buildInfoResult.Response["gitVersion"].AsString, // gitVersion
                            buildInfoResult.Response["sysInfo"].AsString, // sysInfo
                            buildInfoResult.Response["version"].AsString // versionString
                        );
                    } finally {
                        connectionPool.ReleaseConnection(connection);
                    }
                } catch {
                    connectionPool.Close();
                    throw;
                }

                State = MongoServerState.Connected;
                this.connectionPool = connectionPool;
            } catch (Exception ex) {
                State = MongoServerState.Disconnected;
                connectException = ex;
                throw;
            }
        }
 // constructors
 /// <summary>
 /// Initializes a new instance of the <see cref="MongoServerInstance"/> class.
 /// </summary>
 /// <param name="server">The server.</param>
 /// <param name="address">The address.</param>
 internal MongoServerInstance(MongoServer server, MongoServerAddress address)
 {
     _server = server;
     _address = address;
     _sequentialId = Interlocked.Increment(ref __nextSequentialId);
     _maxDocumentSize = MongoDefaults.MaxDocumentSize;
     _maxMessageLength = MongoDefaults.MaxMessageLength;
     _state = MongoServerState.Disconnected;
     _instanceType = MongoServerInstanceType.Unknown;
     _connectionPool = new MongoConnectionPool(this);
     _pingTimeAggregator = new PingTimeAggregator(5);
     _stateVerificationTimer = new Timer(o => StateVerificationTimerCallback(), null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
     // Console.WriteLine("MongoServerInstance[{0}]: {1}", sequentialId, address);
 }
Example #12
0
 // constructors
 internal MongoConnection(MongoConnectionPool connectionPool)
     : this(connectionPool.ServerInstance)
 {
     _connectionPool = connectionPool;
     _generationId   = connectionPool.GenerationId;
 }
 internal void Disconnect() {
     if (state != MongoServerState.Disconnected) {
         try {
             connectionPool.Close();
             connectionPool = null;
         } finally {
             State = MongoServerState.Disconnected;
         }
     }
 }
        internal void Connect(
            bool slaveOk
        ) {
            lock (serverInstanceLock) {
                // note: don't check that state is Disconnected here
                // when reconnecting to a replica set state can transition from Connected -> Connecting -> Connected

                State = MongoServerState.Connecting;
                connectException = null;
                try {
                    endPoint = address.ToIPEndPoint(server.Settings.AddressFamily);

                    if (connectionPool == null) {
                        connectionPool = new MongoConnectionPool(this);
                    }

                    try {
                        var connection = connectionPool.AcquireConnection(null);
                        try {
                            try {
                                var isMasterCommand = new CommandDocument("ismaster", 1);
                                isMasterResult = connection.RunCommand("admin.$cmd", QueryFlags.SlaveOk, isMasterCommand);
                            } catch (MongoCommandException ex) {
                                isMasterResult = ex.CommandResult;
                                throw;
                            }

                            isPrimary = isMasterResult.Response["ismaster", false].ToBoolean();
                            isSecondary = isMasterResult.Response["secondary", false].ToBoolean();
                            isPassive = isMasterResult.Response["passive", false].ToBoolean();
                            isArbiter = isMasterResult.Response["arbiterOnly", false].ToBoolean();
                            // workaround for CSHARP-273
                            if (isPassive && isArbiter) { isPassive = false; }
                            if (!isPrimary && !slaveOk) {
                                throw new MongoConnectionException("Server is not a primary and SlaveOk is false.");
                            }

                            maxDocumentSize = isMasterResult.Response["maxBsonObjectSize", MongoDefaults.MaxDocumentSize].ToInt32();
                            maxMessageLength = Math.Max(MongoDefaults.MaxMessageLength, maxDocumentSize + 1024); // derived from maxDocumentSize

                            var buildInfoCommand = new CommandDocument("buildinfo", 1);
                            var buildInfoResult = connection.RunCommand("admin.$cmd", QueryFlags.SlaveOk, buildInfoCommand);
                            buildInfo = new MongoServerBuildInfo(
                                buildInfoResult.Response["bits"].ToInt32(), // bits
                                buildInfoResult.Response["gitVersion"].AsString, // gitVersion
                                buildInfoResult.Response["sysInfo"].AsString, // sysInfo
                                buildInfoResult.Response["version"].AsString // versionString
                            );
                        } finally {
                            connection.ConnectionPool.ReleaseConnection(connection);
                        }
                    } catch {
                        if (connectionPool != null) {
                            connectionPool.Close();
                            connectionPool = null;
                        }
                        throw;
                    }

                    // for the primary only immediately start creating connections to reach MinConnectionPoolSize
                    if (isPrimary) {
                        connectionPool.CreateInitialConnections(); // will be done on a background thread
                    }

                    State = MongoServerState.Connected;
                } catch (Exception ex) {
                    State = MongoServerState.Disconnected;
                    connectException = ex;
                    throw;
                }
            }
        }