/// <exception cref="System.Net.Sockets.SocketException">Throws a SocketException when the connection could not be established with the host</exception> /// <exception cref="AuthenticationException" /> /// <exception cref="UnsupportedProtocolVersionException"></exception> private Connection CreateConnection() { _logger.Info("Creating a new connection to the host " + Host.Address.ToString()); var c = new Connection(ProtocolVersion, Host.Address, Configuration); c.Init(); if (Configuration.PoolingOptions.GetHeartBeatInterval() != null) { //Heartbeat is enabled, subscribe for possible exceptions c.OnIdleRequestException += OnIdleRequestException; } return c; }
/// <summary> /// Gets the connection with the minimum number of InFlight requests. /// Only checks for index + 1 and index, to avoid a loop of all connections. /// </summary> public static Connection MinInFlight(Connection[] connections, ref int connectionIndex) { if (connections.Length == 1) { return connections[0]; } //It is very likely that the amount of InFlight requests per connection is the same //Do round robin between connections, skipping connections that have more in flight requests var index = Interlocked.Increment(ref connectionIndex); if (index > ConnectionIndexOverflow) { //Overflow protection, not exactly thread-safe but we can live with it Interlocked.Exchange(ref connectionIndex, 0); } var currentConnection = connections[index % connections.Length]; var previousConnection = connections[(index - 1)%connections.Length]; if (previousConnection.InFlight < currentConnection.InFlight) { return previousConnection; } return currentConnection; }
public void CheckHealth(Connection c) { if (c.TimedOutOperations < _config.SocketOptions.DefunctReadTimeoutThreshold) { return; } //We are in the default thread-pool (non-io thread) //Defunct: close it and remove it from the pool _connections.Remove(c); c.Dispose(); }
private void TransitionCreationTask(TaskCompletionSource<Connection[]> tcs, Connection[] result, Exception ex = null) { if (ex != null) { tcs.TrySetException(ex); } else if (result != null) { tcs.TrySetResult(result); } else { tcs.TrySetException(new DriverInternalError("Creation task must transition from a result or an exception")); } Interlocked.Exchange(ref _creationTcs, null); }
/// <exception cref="System.Net.Sockets.SocketException">Throws a SocketException when the connection could not be established with the host</exception> /// <exception cref="AuthenticationException" /> /// <exception cref="UnsupportedProtocolVersionException"></exception> internal virtual Task<Connection> CreateConnection() { Logger.Info("Creating a new connection to the host " + _host.Address); var c = new Connection(_serializer, _host.Address, _config); return c.Open().ContinueWith(t => { if (t.Status == TaskStatus.RanToCompletion) { if (_config.GetPoolingOptions(_serializer.ProtocolVersion).GetHeartBeatInterval() > 0) { //Heartbeat is enabled, subscribe for possible exceptions c.OnIdleRequestException += OnIdleRequestException; } return c; } Logger.Info("The connection to {0} could not be opened", _host.Address); c.Dispose(); if (t.Exception != null) { t.Exception.Handle(_ => true); Logger.Error(t.Exception.InnerException); throw t.Exception.InnerException; } throw new TaskCanceledException("The connection creation task was cancelled"); }, TaskContinuationOptions.ExecuteSynchronously); }
/// <summary> /// Gets the connection with the minimum number of InFlight requests /// </summary> public Connection MinInFlight(Connection[] connections) { if (connections.Length == 1) { return connections[0]; } //It is very likely that the amount of InFlight requests per connection is the same //Do round robin between connections var list = new LinkedList<Connection>(); list.AddLast(connections[0]); var lastValue = connections[0].InFlight; for (var i = 1; i < connections.Length; i++) { var c = connections[i]; var inFlight = c.InFlight; if (inFlight > lastValue) { continue; } if (inFlight == lastValue) { list.AddLast(c); continue; } lastValue = inFlight; list = new LinkedList<Connection>(); list.AddLast(connections[0]); } var index = Interlocked.Increment(ref _connectionIndex); if (index > ConnectionIndexOverflow) { //Overflow protection, not exactly thread-safe but we can live with it Interlocked.Exchange(ref _connectionIndex, 0); } return list.Skip(index % list.Count).First(); }