Exemple #1
0
        /// <summary>
        /// Initializes a new instance of the BaseSession class based on the specified connection string.
        /// </summary>
        /// <param name="connectionString">The connection used to create the session.</param>
        /// <exception cref="ArgumentNullException"><paramref name="connectionString"/> is <c>null</c>.</exception>
        /// <exception cref="UriFormatException">Unable to parse the <paramref name="connectionString"/> when
        /// in URI format.</exception>
        /// <remarks>
        /// <para>When using Unix sockets the <c>protocol=unix</c> or <c>protocol=unixsocket</c> connection option is required.
        /// This will enable elements passed in the <c>server</c> connection option to be treated as Unix sockets. The user is also required
        /// to explicitly set <c>sslmode</c> to <c>none</c> since X Plugin does not support SSL when using Unix sockets. Note that
        /// <c>protocol=unix</c> and <c>protocol=unixsocket</c> are synonyms.</para>
        /// <para>&#160;</para>
        /// <para>Multiple hosts can be specified as part of the <paramref name="connectionString"/>,
        /// which will enable client side failover when trying to establish a connection.</para>
        /// <para>&#160;</para>
        /// <para>Connection string examples (in URI format):
        /// <para />- mysqlx://test:test@[192.1.10.10,localhost]
        /// <para />- mysqlx://test:test@[192.1.10.10,127.0.0.1]
        /// <para />- mysqlx://root:@[../tmp/mysqlx.sock,/tmp/mysqld.sock]?protocol=unix&#38;sslmode=none
        /// <para />- mysqlx://test:test@[192.1.10.10:33060,127.0.0.1:33060]
        /// <para />- mysqlx://test:test@[192.1.10.10,120.0.0.2:22000,[::1]:33060]/test?connectiontimeout=10
        /// <para />- mysqlx://test:test@[(address=server.example,priority=20),(address=127.0.0.1,priority=100)]
        /// <para />- mysqlx://test:test@[(address=server.example,priority=100),(address=127.0.0.1,priority=75),(address=192.0.10.56,priority=25)]
        /// </para>
        /// <para>&#160;</para>
        /// <para>Connection string examples (in basic format):
        /// <para />- server=10.10.10.10,localhost;port=33060;uid=test;password=test;
        /// <para />- host=10.10.10.10,192.101.10.2,localhost;port=5202;uid=test;password=test;
        /// <para />- host=./tmp/mysqld.sock,/var/run/mysqldx.sock;port=5202;uid=root;protocol=unix;sslmode=none;
        /// <para />- server=(address=server.example,priority=20),(address=127.0.0.1,priority=100);port=33060;uid=test;password=test;
        /// <para />- server=(address=server.example,priority=100),(address=127.0.0.1,priority=75),(address=192.0.10.56,priority=25);port=33060;uid=test;password=test;
        /// </para>
        /// <para>&#160;</para>
        /// <para>Failover methods</para>
        /// <para>- Sequential: Connection attempts will be performed in a sequential order, that is, one after another until
        /// a connection is successful or all the elements from the list have been tried.
        /// </para>
        /// <para>- Priority based: If a priority is provided, the connection attemps will be performed in descending order, starting
        /// with the host with the highest priority. Priority must be a value between 0 and 100. Additionally, it is required to either
        /// give a priority for every host or no priority to any host.
        /// </para>
        /// </remarks>
        public BaseSession(string connectionString)
        {
            if (string.IsNullOrWhiteSpace(connectionString))
            {
                throw new ArgumentNullException("connectionString");
            }

            this.connectionString = ParseConnectionString(connectionString);

            if (FailoverManager.FailoverGroup != null)
            {
                // Multiple hosts were specified.
                _internalSession = FailoverManager.AttemptConnection(this.connectionString, out this.connectionString);
                Settings         = new MySqlConnectionStringBuilder(this.connectionString);
            }
            else
            {
                // A single host was specified.
                Settings         = new MySqlConnectionStringBuilder(this.connectionString);
                _internalSession = InternalSession.GetSession(Settings);
            }

            if (!string.IsNullOrWhiteSpace(Settings.Database))
            {
                GetSchema(Settings.Database);
            }
        }
        /// <summary>
        /// Initializes a new instance of the BaseSession class based on the specified connection string.
        /// </summary>
        /// <param name="connectionString">The connection used to create the session.</param>
        /// <exception cref="ArgumentNullException"><paramref name="connectionString"/> is <c>null</c>.</exception>
        /// <exception cref="UriFormatException">Unable to parse the <paramref name="connectionString"/> when
        /// in URI format.</exception>
        /// <remarks>
        /// <para>When using Unix sockets the <c>protocol=unix</c> or <c>protocol=unixsocket</c> connection option is required.
        /// This will enable elements passed in the <c>server</c> connection option to be treated as Unix sockets. The user is also required
        /// to explicitly set <c>sslmode</c> to <c>none</c> since X Plugin does not support SSL when using Unix sockets. Note that
        /// <c>protocol=unix</c> and <c>protocol=unixsocket</c> are synonyms.</para>
        /// <para>&#160;</para>
        /// <para>Multiple hosts can be specified as part of the <paramref name="connectionString"/>,
        /// which enables client-side failover when trying to establish a connection.</para>
        /// <para>&#160;</para>
        /// <para>Connection URI examples:
        /// <para />- mysqlx://test:test@[192.1.10.10,localhost]
        /// <para />- mysqlx://test:test@[192.1.10.10,127.0.0.1]
        /// <para />- mysqlx://root:@[../tmp/mysqlx.sock,/tmp/mysqld.sock]?protocol=unix&#38;sslmode=none
        /// <para />- mysqlx://test:test@[192.1.10.10:33060,127.0.0.1:33060]
        /// <para />- mysqlx://test:test@[192.1.10.10,120.0.0.2:22000,[::1]:33060]/test?connectiontimeout=10
        /// <para />- mysqlx://test:test@[(address=server.example,priority=20),(address=127.0.0.1,priority=100)]
        /// <para />- mysqlx://test:test@[(address=server.example,priority=100),(address=127.0.0.1,priority=75),(address=192.0.10.56,priority=25)]
        /// </para>
        /// <para>&#160;</para>
        /// <para>Connection string examples:
        /// <para />- server=10.10.10.10,localhost;port=33060;uid=test;password=test;
        /// <para />- host=10.10.10.10,192.101.10.2,localhost;port=5202;uid=test;password=test;
        /// <para />- host=./tmp/mysqld.sock,/var/run/mysqldx.sock;port=5202;uid=root;protocol=unix;sslmode=none;
        /// <para />- server=(address=server.example,priority=20),(address=127.0.0.1,priority=100);port=33060;uid=test;password=test;
        /// <para />- server=(address=server.example,priority=100),(address=127.0.0.1,priority=75),(address=192.0.10.56,priority=25);port=33060;uid=test;password=test;
        /// </para>
        /// <para>&#160;</para>
        /// <para>Failover methods</para>
        /// <para>- Sequential: Connection attempts will be performed in a sequential order, that is, one after another until
        /// a connection is successful or all the elements from the list have been tried.
        /// </para>
        /// <para>- Priority based: If a priority is provided, the connection attemps will be performed in descending order, starting
        /// with the host with the highest priority. Priority must be a value between 0 and 100. Additionally, it is required to either
        /// give a priority for every host or no priority to any host.
        /// </para>
        /// </remarks>
        internal BaseSession(string connectionString, Client client = null) : this()
        {
            if (string.IsNullOrWhiteSpace(connectionString))
            {
                throw new ArgumentNullException("connectionString");
            }

            _client = client;
            this._connectionString = ParseConnectionData(connectionString);

            // Multiple hosts were specified.
            if (FailoverManager.FailoverGroup != null)
            {
                _internalSession          = FailoverManager.AttemptConnection(this._connectionString, out this._connectionString);
                Settings.ConnectionString = this._connectionString;
                Settings.AnalyzeConnectionString(this._connectionString, true);
            }
            // A single host was specified.
            else
            {
                Settings.ConnectionString = _connectionString;
                if (!(_connectionString.Contains("sslmode") || _connectionString.Contains("ssl mode") || _connectionString.Contains("ssl-mode")))
                {
                    Settings.SslMode = MySqlSslMode.Required;
                }
                Settings.AnalyzeConnectionString(this._connectionString, true);
                _internalSession = InternalSession.GetSession(Settings);
            }

            // Set the default schema if provided by the user.
            if (!string.IsNullOrWhiteSpace(Settings.Database))
            {
                DefaultSchema = GetSchema(Settings.Database);
            }
        }
Exemple #3
0
        /// <summary>
        /// Attempts to establish a connection to a host specified from the list.
        /// </summary>
        /// <param name="originalConnectionString">The original connection string set by the user.</param>
        /// <param name="connectionString">An out parameter that stores the updated connection string.</param>
        /// <returns>An <see cref="InternalSession"/> instance if the connection was succesfully established, a <see cref="MySqlException"/> exception is thrown otherwise.</returns>
        internal static InternalSession AttemptConnection(string originalConnectionString, out string connectionString)
        {
            if (FailoverGroup == null || originalConnectionString == null)
            {
                connectionString = null;
                return(null);
            }

            XServer currentHost = FailoverGroup.ActiveHost;
            string  initialHost = currentHost.Host;
            MySqlXConnectionStringBuilder Settings = null;
            InternalSession  internalSession       = null;
            TimeoutException timeoutException      = null;

            do
            {
                // Attempt to connect to each host by retrieving the next host based on the failover method being used.
                connectionString = "server=" + currentHost.Host + ";" + originalConnectionString.Substring(originalConnectionString.IndexOf(';') + 1);
                Settings         = new MySqlXConnectionStringBuilder(connectionString);
                if (currentHost != null && currentHost.Port != -1)
                {
                    Settings.Port = (uint)currentHost.Port;
                }
                if (currentHost.Host == initialHost)
                {
                    string exTimeOutMessage = Settings.ConnectTimeout == 0 ? ResourcesX.TimeOutMultipleHost0ms : String.Format(ResourcesX.TimeOutMultipleHost, Settings.ConnectTimeout);
                    timeoutException = new TimeoutException(exTimeOutMessage);
                }

                try
                {
                    internalSession  = InternalSession.GetSession(Settings);
                    timeoutException = null;
                }
                catch (Exception ex) { if (!(ex is TimeoutException))
                                       {
                                           timeoutException = null;
                                       }
                }

                if (internalSession != null)
                {
                    break;
                }

                currentHost = FailoverGroup.GetNextHost();
            }while (currentHost.Host != initialHost);

            // All connection attempts failed.
            if (timeoutException != null)
            {
                throw timeoutException;
            }
            if (internalSession == null)
            {
                throw new MySqlException(Resources.UnableToConnectToHost);
            }

            return(internalSession);
        }
 public void AddSession(Socket s,TcpServer server)
 {
     lock (_lock)
     {
         InternalSession session = new InternalSession(server, s);
         mDicSession[s] = session;
     }
 }
Exemple #5
0
 internal Result(InternalSession session) : base(session)
 {
     if (session == null)
     {
         return;
     }
     session.GetProtocol().CloseResult(this);
 }
Exemple #6
0
 internal Result(InternalSession session) : base(session)
 {
     if (session == null)
     {
         return;
     }
     GeneratedIds = new ReadOnlyCollection <string>(_documentIds);
     session.GetProtocol().CloseResult(this);
 }
Exemple #7
0
            public void ShouldDelegateToAsyncSession()
            {
                var asyncSession = new Mock <IInternalAsyncSession>();
                var session      = new InternalSession(asyncSession.Object, Mock.Of <IRetryLogic>(),
                                                       Mock.Of <BlockingExecutor>());

                var bookmark = session.LastBookmark;

                asyncSession.Verify(x => x.LastBookmark, Times.Once);
            }
Exemple #8
0
        /// <summary>
        /// Get a handle to the session manager and request the session object by id
        /// this is also the signal to the session manager that this NativeSessionHost is ready
        /// </summary>
        /// <param name="creatorProcessId"></param>
        /// <param name="sessionId"></param>

        private static void RegisterSession2(int creatorProcessId, int sessionId)
        {
            SetSessionManagerProcessId(creatorProcessId);

            INativeSessionManager sessionManager = NativeSessionManagerClientFactory.CreateChannel();
            InternalSession       session        = sessionManager.RegisterNativeSessionHost(sessionId);

            ((IClientChannel)sessionManager).Close();
            InternalSession = session;
        }
Exemple #9
0
            public void ShouldDelegateToAsyncSession()
            {
                var asyncSession = new Mock <IInternalAsyncSession>();
                var session      = new InternalSession(asyncSession.Object, Mock.Of <IRetryLogic>(),
                                                       Mock.Of <BlockingExecutor>());

                var config = session.SessionConfig;

                asyncSession.Verify(x => x.SessionConfig, Times.Once);
            }
Exemple #10
0
        /// <summary>
        /// Initializes a new instance of the BaseSession class based on the specified anonymous type object.
        /// </summary>
        /// <param name="connectionData">The connection data as an anonymous type used to create the session.</param>
        /// <exception cref="ArgumentNullException"><paramref name="connectionData"/> is null.</exception>
        /// <remarks>
        /// <para>Multiple hosts can be specified as part of the <paramref name="connectionData"/>, which will enable client-side failover when trying to
        /// establish a connection.</para>
        /// <para>&#160;</para>
        /// <para>To assign multiple hosts create a property similar to the connection string examples (in basic format) shown in
        /// <see cref="BaseSession(string)"/>. Note that the value of the property must be a string.
        /// </para>
        /// </remarks>
        public BaseSession(object connectionData)
        {
            if (connectionData == null)
            {
                throw new ArgumentNullException("connectionData");
            }
            var values = Tools.GetDictionaryFromAnonymous(connectionData);

            if (!values.Keys.Any(s => s.ToLowerInvariant() == "port"))
            {
                values.Add("port", newDefaultPort);
            }
            Settings = new MySqlConnectionStringBuilder();
            bool hostsParsed = false;

            foreach (var value in values)
            {
                if (!Settings.ContainsKey(value.Key))
                {
                    throw new KeyNotFoundException(string.Format(ResourcesX.InvalidConnectionStringAttribute, value.Key));
                }
                Settings.SetValue(value.Key, value.Value);
                if (!hostsParsed && !string.IsNullOrEmpty(Settings["server"].ToString()))
                {
                    var server = value.Value.ToString();
                    if (IsUnixSocket(server))
                    {
                        Settings.SetValue(value.Key, server = NormalizeUnixSocket(server));
                    }
                    ParseHostList(server, false);
                    if (FailoverManager.FailoverGroup != null)
                    {
                        Settings["server"] = FailoverManager.FailoverGroup.ActiveHost.Host;
                    }
                    hostsParsed = true;
                }
            }
            this.connectionString = Settings.ToString();

            if (FailoverManager.FailoverGroup != null)
            {
                // Multiple hosts were specified.
                _internalSession = FailoverManager.AttemptConnection(this.connectionString, out this.connectionString);
                Settings         = new MySqlConnectionStringBuilder(this.connectionString);
            }
            else
            {
                _internalSession = InternalSession.GetSession(Settings);
            }

            if (!string.IsNullOrWhiteSpace(Settings.Database))
            {
                GetSchema(Settings.Database);
            }
        }
Exemple #11
0
        public async Task Should_RetryOnNextNodes_When_ANodeIsPaused(bool streamMode)
        {
            var pausedNode = TestCluster.GetNode(2);

            SetupNewSession(b =>
                            b.WithPoolingOptions(
                                new PoolingOptions()
                                .SetCoreConnectionsPerHost(HostDistance.Local, 1)
                                .SetMaxConnectionsPerHost(HostDistance.Local, 1))
                            .WithSocketOptions(
                                new SocketOptions()
                                .SetReadTimeoutMillis(2000)
                                .SetStreamMode(streamMode)
                                .SetDefunctReadTimeoutThreshold(int.MaxValue)));

            var maxRequestsPerConnection =
                Session.Cluster.Configuration
                .GetOrCreatePoolingOptions(Session.Cluster.Metadata.ControlConnection.ProtocolVersion)
                .GetMaxRequestsPerConnection();

            var tenKbBuffer = new byte[10240];

            await pausedNode.PauseReadsAsync().ConfigureAwait(false);

            // send number of requests = max pending
            var requests =
                Enumerable.Repeat(0, maxRequestsPerConnection * Session.Cluster.AllHosts().Count)
                .Select(i => Session.ExecuteAsync(new SimpleStatement("INSERT INTO table1 (id) VALUES (?)", tenKbBuffer))).ToList();

            var pools                   = InternalSession.GetPools().ToList();
            var runningNodesPools       = pools.Where(kvp => !kvp.Key.Equals(pausedNode.IpEndPoint));
            var pausedNodePool          = pools.Single(kvp => kvp.Key.Equals(pausedNode.IpEndPoint));
            var connections             = pools.SelectMany(kvp => kvp.Value.ConnectionsSnapshot).ToList();
            var runningNodesConnections = runningNodesPools.SelectMany(kvp => kvp.Value.ConnectionsSnapshot).ToList();
            var pausedNodeConnections   = pausedNodePool.Value.ConnectionsSnapshot;

            await Task.WhenAll(requests).ConfigureAwait(false);

            await AssertRetryUntilWriteQueueStabilizesAsync(connections).ConfigureAwait(false);

            TestHelper.RetryAssert(
                () =>
            {
                Assert.IsTrue(runningNodesConnections.All(c => c.InFlight == 0));
                Assert.IsTrue(runningNodesConnections.All(c => c.WriteQueueLength == 0));
                Assert.IsTrue(runningNodesConnections.All(c => c.PendingOperationsMapLength == 0));
            },
                100,
                100);

            Assert.IsTrue(pausedNodeConnections.All(c => c.InFlight > 0));
            Assert.IsTrue(pausedNodeConnections.All(c => c.WriteQueueLength > 0));
            Assert.IsTrue(pausedNodeConnections.All(c => c.PendingOperationsMapLength > 0));
        }
Exemple #12
0
        /// <summary>
        /// Drops the database/schema with the given name.
        /// </summary>
        /// <param name="schema">The name of the schema.</param>
        /// <exception cref="ArgumentNullException"><paramref name="schema"/> is null.</exception>
        public void DropSchema(string schema)
        {
            if (string.IsNullOrWhiteSpace(schema))
            {
                throw new ArgumentNullException(nameof(schema));
            }
            Schema s = this.GetSchema(schema);

            if (!s.ExistsInDatabase())
            {
                return;
            }
            InternalSession.ExecuteSqlNonQuery("DROP DATABASE `" + schema + "`");
        }
Exemple #13
0
 /// <summary>
 /// Closes this session or releases it to the pool.
 /// </summary>
 public void Close()
 {
     if (XSession.SessionState != SessionState.Closed)
     {
         if (_client == null)
         {
             CloseFully();
         }
         else
         {
             _client.ReleaseSession(this);
             XSession.SetState(SessionState.Closed, false);
             _internalSession = null;
         }
     }
 }
        /// <summary>
        /// Initializes a new instance of the BaseSession class based on the specified connection string.
        /// </summary>
        /// <param name="connectionString">The connection used to create the session.</param>
        /// <param name="client">A <see cref="Client"/> object.</param>
        /// <exception cref="ArgumentNullException"><paramref name="connectionString"/> is <c>null</c>.</exception>
        /// <exception cref="UriFormatException">Unable to parse the <paramref name="connectionString"/> when
        /// in URI format.</exception>
        /// <remarks>
        /// <para>When using Unix sockets the <c>protocol=unix</c> or <c>protocol=unixsocket</c> connection option is required.
        /// This will enable elements passed in the <c>server</c> connection option to be treated as Unix sockets. The user is also required
        /// to explicitly set <c>sslmode</c> to <c>none</c> since X Plugin does not support SSL when using Unix sockets. Note that
        /// <c>protocol=unix</c> and <c>protocol=unixsocket</c> are synonyms.</para>
        /// <para>&#160;</para>
        /// <para>Multiple hosts can be specified as part of the <paramref name="connectionString"/>,
        /// which enables client-side failover when trying to establish a connection.</para>
        /// <para>&#160;</para>
        /// <para>Connection URI examples:
        /// <para />- mysqlx://test:test@[192.1.10.10,localhost]
        /// <para />- mysqlx://test:test@[192.1.10.10,127.0.0.1]
        /// <para />- mysqlx://root:@[../tmp/mysqlx.sock,/tmp/mysqld.sock]?protocol=unix&#38;sslmode=none
        /// <para />- mysqlx://test:test@[192.1.10.10:33060,127.0.0.1:33060]
        /// <para />- mysqlx://test:test@[192.1.10.10,120.0.0.2:22000,[::1]:33060]/test?connectiontimeout=10
        /// <para />- mysqlx://test:test@[(address=server.example,priority=20),(address=127.0.0.1,priority=100)]
        /// <para />- mysqlx://test:test@[(address=server.example,priority=100),(address=127.0.0.1,priority=75),(address=192.0.10.56,priority=25)]
        /// </para>
        /// <para>&#160;</para>
        /// <para>Connection string examples:
        /// <para />- server=10.10.10.10,localhost;port=33060;uid=test;password=test;
        /// <para />- host=10.10.10.10,192.101.10.2,localhost;port=5202;uid=test;password=test;
        /// <para />- host=./tmp/mysqld.sock,/var/run/mysqldx.sock;port=5202;uid=root;protocol=unix;sslmode=none;
        /// <para />- server=(address=server.example,priority=20),(address=127.0.0.1,priority=100);port=33060;uid=test;password=test;
        /// <para />- server=(address=server.example,priority=100),(address=127.0.0.1,priority=75),(address=192.0.10.56,priority=25);port=33060;uid=test;password=test;
        /// </para>
        /// <para>&#160;</para>
        /// <para>Failover methods</para>
        /// <para>- Sequential: Connection attempts will be performed in a sequential order, that is, one after another until
        /// a connection is successful or all the elements from the list have been tried.
        /// </para>
        /// <para>- Priority based: If a priority is provided, the connection attemps will be performed in descending order, starting
        /// with the host with the highest priority. Priority must be a value between 0 and 100. Additionally, it is required to either
        /// give a priority for every host or no priority to any host.
        /// </para>
        /// </remarks>
        internal BaseSession(string connectionString, Client client = null) : this()
        {
            if (string.IsNullOrWhiteSpace(connectionString))
            {
                throw new ArgumentNullException("connectionString");
            }

            _client = client;
            this._connectionString = ParseConnectionData(connectionString, client);

            // Multiple hosts were specified.
            if (FailoverManager.FailoverGroup != null && FailoverManager.FailoverGroup.Hosts?.Count > 1)
            {
                _internalSession          = FailoverManager.AttemptConnectionXProtocol(this._connectionString, out this._connectionString, _isDefaultPort, client);
                Settings.ConnectionString = this._connectionString;
                Settings.AnalyzeConnectionString(this._connectionString, true, _isDefaultPort);
            }
            // A single host was specified.
            else
            {
                Settings.ConnectionString = _connectionString;
                if (!(_connectionString.Contains("sslmode") || _connectionString.Contains("ssl mode") || _connectionString.Contains("ssl-mode")))
                {
                    Settings.SslMode = MySqlSslMode.Required;
                }
                Settings.AnalyzeConnectionString(this._connectionString, true, _isDefaultPort);

                if (Settings.DnsSrv)
                {
                    var dnsSrvRecords = DnsResolver.GetDnsSrvRecords(Settings.Server);
                    FailoverManager.SetHostList(dnsSrvRecords.ConvertAll(r => new FailoverServer(r.Target, r.Port, r.Priority)),
                                                FailoverMethod.Sequential);
                    _internalSession          = FailoverManager.AttemptConnectionXProtocol(this._connectionString, out this._connectionString, _isDefaultPort, client);
                    Settings.ConnectionString = this._connectionString;
                }
                else
                {
                    _internalSession = InternalSession.GetSession(Settings);
                }
            }

            // Set the default schema if provided by the user.
            if (!string.IsNullOrWhiteSpace(Settings.Database))
            {
                DefaultSchema = GetSchema(Settings.Database);
            }
        }
Exemple #15
0
        internal BaseResult(InternalSession session)
        {
            if (session == null)
            {
                return;
            }
            _session = session;

            // if we have an active resultset then we must buffer it entirely
            if (session.ActiveResult != null)
            {
                session.ActiveResult.Buffer();
                session.ActiveResult = null;
            }

            _hasData = Protocol.HasData(this);
            if (_hasData)
            {
                session.ActiveResult = this;
            }
        }
Exemple #16
0
        /// <summary>
        /// Update the ServiceHost with the last invocation time
        /// </summary>
        /// <param name="idleTime"></param>

        static void UpdateServiceHostWithLastInvocationTime(DateTime lastInvocationActiveTime)
        {
            try
            {
                if (InternalSession == null)
                {
                    return;
                }

                if (LogServiceCalls)
                {
                    DebugLog.Message("UpdateServiceHostWithLastInvocationTime, Session: " + InternalSession.Id + ", Process: " + Process.GetCurrentProcess().Id);
                }

                InternalSession.LastFreshenDT = lastInvocationActiveTime;                 // send last invocation time

                SetSessionManagerProcessId(ServiceHostProcessId);

                INativeSessionManager sessionManager = NativeSessionManagerClientFactory.CreateChannel();
                InternalSession       session        = sessionManager.FreshenNativeSession(InternalSession);
                ((IClientChannel)sessionManager).Close();
            }

            catch (Exception ex)
            {
                string msgToIgnore = "There was no endpoint listening at net.pipe:";
                if (Lex.Contains(ex.Message, msgToIgnore))
                {
                    return;
                }

                DebugLog.Message("Session: " + InternalSession.Id + ", Process: " + Process.GetCurrentProcess().Id + ", " + DebugLog.FormatExceptionMessage(ex));
            }

            return;
        }
Exemple #17
0
 /// <summary>
 /// Rolls back the current transaction.
 /// </summary>
 public Result Rollback()
 {
     return(InternalSession.ExecuteSqlNonQuery("ROLLBACK"));
 }
Exemple #18
0
 internal BaseSession(InternalSession internalSession, Client client)
 {
     _internalSession = internalSession;
     Settings         = internalSession.Settings;
     _client          = client;
 }
Exemple #19
0
        /// <summary>
        /// Initializes a new instance of the BaseSession class based on the specified anonymous type object.
        /// </summary>
        /// <param name="connectionData">The connection data as an anonymous type used to create the session.</param>
        /// <exception cref="ArgumentNullException"><paramref name="connectionData"/> is null.</exception>
        /// <remarks>
        /// <para>Multiple hosts can be specified as part of the <paramref name="connectionData"/>, which enables client-side failover when trying to
        /// establish a connection.</para>
        /// <para>&#160;</para>
        /// <para>To assign multiple hosts, create a property similar to the connection string examples shown in
        /// <see cref="BaseSession(string)"/>. Note that the value of the property must be a string.
        /// </para>
        /// </remarks>
        internal BaseSession(object connectionData, Client client = null) : this()
        {
            if (connectionData == null)
            {
                throw new ArgumentNullException("connectionData");
            }

            _client = client;

            var values = Tools.GetDictionaryFromAnonymous(connectionData);

            if (!values.Keys.Any(s => s.ToLowerInvariant() == PORT_CONNECTION_OPTION_KEYWORD))
            {
                values.Add(PORT_CONNECTION_OPTION_KEYWORD, X_PROTOCOL_DEFAULT_PORT);
            }

            bool hostsParsed = false;

            foreach (var value in values)
            {
                if (!Settings.ContainsKey(value.Key))
                {
                    throw new KeyNotFoundException(string.Format(ResourcesX.InvalidConnectionStringAttribute, value.Key));
                }

                Settings.SetValue(value.Key, value.Value);
                if (!hostsParsed && !string.IsNullOrEmpty(Settings[SERVER_CONNECTION_OPTION_KEYWORD].ToString()))
                {
                    var server = value.Value.ToString();
                    if (IsUnixSocket(server))
                    {
                        Settings.SetValue(value.Key, server = NormalizeUnixSocket(server));
                    }

                    ParseHostList(server, false);
                    if (FailoverManager.FailoverGroup != null)
                    {
                        Settings[SERVER_CONNECTION_OPTION_KEYWORD] = null;
                    }

                    hostsParsed = true;
                }
            }
            this._connectionString = Settings.ToString();

            Settings.AnalyzeConnectionString(this._connectionString, true);
            if (FailoverManager.FailoverGroup != null)
            {
                // Multiple hosts were specified.
                _internalSession          = FailoverManager.AttemptConnection(this._connectionString, out this._connectionString);
                Settings.ConnectionString = _connectionString;
            }
            else
            {
                _internalSession = InternalSession.GetSession(Settings);
            }

            if (!string.IsNullOrWhiteSpace(Settings.Database))
            {
                DefaultSchema = GetSchema(Settings.Database);
            }
        }
Exemple #20
0
        public void BuildIndexFromGraphs(CloudTableClient cloudTableClient)
        {
            //Let the background thread claim the wait handle.
            ThreadPool.QueueUserWorkItem(
                state =>
                    {
                        var registeredGraphs = registeredIndexer.GraphsIndexed;
                        var session = new InternalSession(registeredIndexer.Registry, backingStore);

                        //We use the session to manage to loading and deserialisation of graphs that contribute to the index...
                        session
                            .GetEntireStash()
                            .Matching(
                                _ =>
                                _.Where<StashTypeHierarchy>().AnyOf(registeredGraphs.Select(rg => StashTypeHierarchy.GetConcreteTypeValue(rg.GraphType))))
                            .Materialize();

                        //...but we then use the enrolled persistence events directly to yield the keys for this new index.
                        var graphProjections =
                            session
                                .EnrolledPersistenceEvents
                                .SelectMany(
                                    trackedGraph => registeredIndexer.GetUntypedProjections(trackedGraph.UntypedGraph),
                                    (graph, projection) => new {Projection = (ProjectedIndex)projection, graph.InternalId});

                        backingStore.InTransactionDo(
                            work =>
                                {
                                    foreach(var projection in graphProjections)
                                    {
                                        try
                                        {
                                            Insert(projection.Projection.UntypedKey, projection.InternalId, ((AzureStorageWork)work).ServiceContext);
                                        }
                                        catch(InvalidOperationException ioEx)
                                        {
                                            var storageEx = ioEx.TranslateDataServiceClientException();
                                            if (storageEx.ExtendedErrorInformation.ErrorCode != TableErrorCodeStrings.EntityAlreadyExists)
                                                throw storageEx;
                                            //This is acceptable, as it is possible for another session to insert the key
                                            //before we match it. We carry on.
                                        }
                                    }
                                });

                        session.Abandon();

                        indexCompiled.Set();
                    });
        }
Exemple #21
0
 /// <summary>
 /// Creates a schema/database with the given name.
 /// </summary>
 /// <param name="schema">The name of the schema/database.</param>
 /// <returns>A <see cref="Schema"/> object that matches the recently created schema/database.</returns>
 public Schema CreateSchema(string schema)
 {
     InternalSession.ExecuteSqlNonQuery("CREATE DATABASE `" + schema + "`");
     return(new Schema(this, schema));
 }
Exemple #22
0
 /// <summary>
 /// Removes the named savepoint from the set of savepoints within the current transaction.
 /// </summary>
 /// <param name="name">The name of the transaction savepoint.</param>
 public void ReleaseSavepoint(string name)
 {
     InternalSession.ExecuteSqlNonQuery($"RELEASE SAVEPOINT {name}");
 }
Exemple #23
0
 /// <summary>
 /// Commits the current transaction.
 /// </summary>
 /// <returns>A <see cref="Result"/> object containing the results of the commit operation.</returns>
 public void Commit()
 {
     InternalSession.ExecuteSqlNonQuery("COMMIT");
 }
Exemple #24
0
 /// <summary>
 /// Starts a new transaction.
 /// </summary>
 public void StartTransaction()
 {
     InternalSession.ExecuteSqlNonQuery("START TRANSACTION");
 }
Exemple #25
0
 internal BufferingResult(InternalSession session) : base(session)
 {
     LoadColumnData();
     PageSize  = 20;
     _position = -1;
 }
Exemple #26
0
 /// <summary>
 /// Rolls back the current transaction.
 /// </summary>
 public void Rollback()
 {
     InternalSession.ExecuteSqlNonQuery("ROLLBACK");
 }
Exemple #27
0
 internal RowResult(InternalSession session) : base(session)
 {
 }
Exemple #28
0
 /// <summary>
 /// Sets a named transaction savepoint.
 /// </summary>
 /// <param name="name">The name of the transaction savepoint.</param>
 /// <returns>The name of the transaction savepoint.</returns>
 public string SetSavepoint(string name)
 {
     InternalSession.ExecuteSqlNonQuery($"SAVEPOINT {name}");
     return(name);
 }
Exemple #29
0
        public async Task Should_ContinueRoutingTrafficToNonPausedNodes_When_ANodeIsPaused(bool streamMode)
        {
            var pausedNode = TestCluster.GetNode(2);

            const string profileName = "running-nodes";

            SetupNewSession(b =>
                            b.WithPoolingOptions(
                                new PoolingOptions()
                                .SetCoreConnectionsPerHost(HostDistance.Local, 1)
                                .SetMaxConnectionsPerHost(HostDistance.Local, 1))
                            .WithSocketOptions(
                                new SocketOptions()
                                .SetReadTimeoutMillis(120000)
                                .SetStreamMode(streamMode))
                            .WithExecutionProfiles(opt => opt
                                                   .WithProfile(profileName, profile => profile
                                                                .WithLoadBalancingPolicy(
                                                                    new TestDisallowListLbp(
                                                                        Cassandra.Policies.NewDefaultLoadBalancingPolicy("dc1"))))));

            var maxRequestsPerConnection =
                Session.Cluster.Configuration
                .GetOrCreatePoolingOptions(Session.Cluster.Metadata.ControlConnection.ProtocolVersion)
                .GetMaxRequestsPerConnection();

            var tenKbBuffer = new byte[10240];

            await pausedNode.PauseReadsAsync().ConfigureAwait(false);

            // send number of requests = max pending
            var requests =
                Enumerable.Repeat(0, maxRequestsPerConnection * Session.Cluster.AllHosts().Count)
                .Select(i => Session.ExecuteAsync(new SimpleStatement("INSERT INTO table1 (id) VALUES (?)", tenKbBuffer))).ToList();

            try
            {
                var pools                   = InternalSession.GetPools().ToList();
                var runningNodesPools       = pools.Where(kvp => !kvp.Key.Equals(pausedNode.IpEndPoint));
                var pausedNodePool          = pools.Single(kvp => kvp.Key.Equals(pausedNode.IpEndPoint));
                var connections             = pools.SelectMany(kvp => kvp.Value.ConnectionsSnapshot).ToList();
                var runningNodesConnections = runningNodesPools.SelectMany(kvp => kvp.Value.ConnectionsSnapshot).ToList();
                var pausedNodeConnections   = pausedNodePool.Value.ConnectionsSnapshot;

                await AssertRetryUntilWriteQueueStabilizesAsync(connections).ConfigureAwait(false);

                TestHelper.RetryAssert(
                    () =>
                {
                    Assert.IsTrue(runningNodesConnections.All(c => c.InFlight == 0));
                    Assert.IsTrue(runningNodesConnections.All(c => c.WriteQueueLength == 0));
                    Assert.IsTrue(runningNodesConnections.All(c => c.PendingOperationsMapLength == 0));
                },
                    100,
                    100);

                Assert.IsTrue(pausedNodeConnections.All(c => c.InFlight > 0));
                Assert.IsTrue(pausedNodeConnections.All(c => c.WriteQueueLength > 0));
                Assert.IsTrue(pausedNodeConnections.All(c => c.PendingOperationsMapLength > 0));

                var writeQueueLengths = pausedNodeConnections.Select(c => c.WriteQueueLength);

                Assert.AreEqual(pausedNodeConnections.Sum(c => c.InFlight), requests.Count(t => !t.IsCompleted && !t.IsFaulted));

                // these should succeed because we are not hitting the paused node with the custom profile
                var moreRequests =
                    Enumerable.Range(0, 100)
                    .Select(i => Session.ExecuteAsync(
                                new SimpleStatement("INSERT INTO table1 (id) VALUES (?)", tenKbBuffer),
                                profileName))
                    .ToList();

                await Task.WhenAll(moreRequests).ConfigureAwait(false);

                Assert.IsTrue(moreRequests.All(t => t.IsCompleted && !t.IsFaulted && !t.IsCanceled));
                CollectionAssert.AreEqual(writeQueueLengths, pausedNodeConnections.Select(c => c.WriteQueueLength));
            }
            finally
            {
                await TestCluster.ResumeReadsAsync().ConfigureAwait(false);

                await(await Task.WhenAny(Task.WhenAll(requests), Task.Delay(5000)).ConfigureAwait(false)).ConfigureAwait(false);
                Assert.IsTrue(requests.All(t => t.IsCompleted && !t.IsFaulted && !t.IsCanceled));
            }
        }
Exemple #30
0
 /// <summary>
 /// Rolls back a transaction to the named savepoint without terminating the transaction.
 /// </summary>
 /// <param name="name">The name of the transaction savepoint.</param>
 public void RollbackTo(string name)
 {
     InternalSession.ExecuteSqlNonQuery($"ROLLBACK TO {name}");
 }
Exemple #31
0
        public async Task Should_KeepOperationsInWriteQueue_When_ServerAppliesTcpBackPressure(bool streamMode)
        {
            SetupNewSession(b =>
                            b.WithPoolingOptions(
                                new PoolingOptions()
                                .SetCoreConnectionsPerHost(HostDistance.Local, 1)
                                .SetMaxConnectionsPerHost(HostDistance.Local, 1))
                            .WithSocketOptions(new SocketOptions()
                                               .SetReadTimeoutMillis(360000)
                                               .SetStreamMode(streamMode)));

            var maxRequestsPerConnection = Session.Cluster.Configuration
                                           .GetOrCreatePoolingOptions(Session.Cluster.Metadata.ControlConnection.ProtocolVersion)
                                           .GetMaxRequestsPerConnection();

            var tenKbBuffer = new byte[10240];

            await TestCluster.PauseReadsAsync().ConfigureAwait(false);

            var pools       = InternalSession.GetPools().ToList();
            var connections = pools.SelectMany(kvp => kvp.Value.ConnectionsSnapshot).ToList();
            var requests    = new List <Task>();

            using (var cts = new CancellationTokenSource())
            {
                var task = Task.Run(
                    async() =>
                {
                    while (!cts.IsCancellationRequested)
                    {
                        requests.Add(Session.ExecuteAsync(new SimpleStatement("INSERT INTO table1 (id) VALUES (?)", tenKbBuffer)));
                        await Task.Yield();
                    }
                },
                    cts.Token);

                await AssertRetryUntilWriteQueueStabilizesAsync(connections, maxRequestsPerConnection).ConfigureAwait(false);

                cts.Cancel();
                await task.ConfigureAwait(false);
            }

            Assert.IsTrue(connections.All(c => c.WriteQueueLength > 0));
            var writeQueueSizes = connections.ToDictionary(c => c, c => c.WriteQueueLength, ReferenceEqualityComparer <IConnection> .Instance);
            var pendingOps      = connections.ToDictionary(c => c, c => c.PendingOperationsMapLength, ReferenceEqualityComparer <IConnection> .Instance);

            // these should fail because we have hit max pending ops
            var moreRequests =
                Enumerable.Range(0, 100)
                .Select(i => Task.Run(() => Session.ExecuteAsync(new SimpleStatement("INSERT INTO table1 (id) VALUES (?)", tenKbBuffer))))
                .ToList();

            try
            {
                try
                {
                    await(await Task.WhenAny(Task.WhenAll(moreRequests), Task.Delay(15000)).ConfigureAwait(false)).ConfigureAwait(false);
                    Assert.Fail("Should throw exception.");
                }
                catch (NoHostAvailableException)
                {
                    // ignored
                }
                var moreFailedRequests = moreRequests.Where(t => t.IsFaulted).ToList();
                Assert.Greater(moreFailedRequests.Count, 1);
                Assert.AreEqual(moreRequests.Count, moreFailedRequests.Count);

                Assert.GreaterOrEqual(connections.Sum(c => c.InFlight), maxRequestsPerConnection * Session.Cluster.AllHosts().Count);

                // ReSharper disable once PossibleNullReferenceException
                Assert.IsTrue(moreFailedRequests.All(t => t.IsFaulted && ((NoHostAvailableException)t.Exception.InnerException).Errors.All(e => e.Value is BusyPoolException)));
                var newWriteQueueSizes =
                    connections.ToDictionary(c => c, c => c.WriteQueueLength, ReferenceEqualityComparer <IConnection> .Instance);
                var newPendingsOps =
                    connections.ToDictionary(c => c, c => c.PendingOperationsMapLength, ReferenceEqualityComparer <IConnection> .Instance);

                foreach (var kvp in writeQueueSizes)
                {
                    Assert.GreaterOrEqual(newWriteQueueSizes[kvp.Key], kvp.Value);
                    Assert.Greater(newWriteQueueSizes[kvp.Key], 1);
                }

                foreach (var kvp in pendingOps)
                {
                    Assert.AreEqual(newPendingsOps[kvp.Key], kvp.Value);
                    Assert.Greater(newPendingsOps[kvp.Key], 1);
                }
            }
            finally
            {
                await TestCluster.ResumeReadsAsync().ConfigureAwait(false);

                try
                {
                    await(await Task.WhenAny(Task.WhenAll(requests), Task.Delay(15000)).ConfigureAwait(false)).ConfigureAwait(false);
                }
                catch (NoHostAvailableException)
                {
                }

                Assert.AreEqual(
                    requests.Count,
                    requests.Count(t => t.IsCompleted && !t.IsFaulted && !t.IsCanceled)
                    + requests.Count(t => t.IsFaulted &&
                                     ((NoHostAvailableException)t.Exception.InnerException)
                                     .Errors.All(e => e.Value is BusyPoolException)));
            }
        }
Exemple #32
0
 internal SqlResult(InternalSession session) : base(session)
 {
 }
        public void it_should_return_itself()
        {
            var sut = new InternalSession(null, null);

            sut.Internalize().ShouldEqual(sut);
        }