private void PopulateConnectionList() { // If the list is empty, create a new one ConnectionsList.Items.Clear(); for (int i = 0, l = App.Settings.Connections.Count; i < l; i++) { string item = App.Settings.Connections[i]; int index = i; JObject info = new JObject(); string[] parts = System.Text.RegularExpressions.Regex.Split(item, "\\{\\{s\\}\\}"); info["name"] = parts[0]; info["server"] = parts[1]; info["username"] = parts[2]; info["password"] = parts[3]; info["database"] = parts[4] ?? string.Empty; ConnectionEntry entry = new ConnectionEntry(info); entry.Selected += (s, e) => { ConnectionsList.Items.MoveCurrentToPosition(index); }; entry.MouseDoubleClick += (s, e) => { StartConnection(s, e); }; ConnectionsList.Items.Add(entry); } }
protected override void OnSetup(IBehaviourContext context) { ConnectionEntry <float> valueInput = Value[context]; ConnectionEntry <int> output = Output[context]; Action updateHandler = () => { if (Method == Rounding.Round) { output.Value = Mathf.RoundToInt(valueInput.Value / Multiple) * Multiple; } else if (Method == Rounding.Floor) { output.Value = Mathf.FloorToInt(valueInput.Value / Multiple) * Multiple; } else if (Method == Rounding.Ceiling) { output.Value = Mathf.CeilToInt(valueInput.Value / Multiple) * Multiple; } }; valueInput.OnAfterChanged += updateHandler; updateHandler(); }
/** * : the EnvCleanup interface. This method * will deallocate resources associated with this * connection. This method can be invoked via a * call to close(), or it can be invoked when the * environment @is being cleaned up after a quercus * request has been processed. */ public void cleanup() { if (log.isLoggable(Level.FINER)) { log.finer(this + " cleanup()"); } Statement savedStmt = _savedStmt; _savedStmt = null; Statement freeStmt = _freeStmt; _freeStmt = null; closeStatement(savedStmt, false); closeStatement(freeStmt, false); ConnectionEntry conn = _conn; _conn = null; if (conn != null) { conn.phpClose(); } }
protected override void OnSetup(IBehaviourContext context) { ConnectionEntry <int> valueAInput = ValueA[context]; ConnectionEntry <int> valueBInput = ValueB[context]; ConnectionEntry <bool> output = Output[context]; Action updateHandler = () => { if (Operator == Comparison.Equal) { output.Value = valueAInput.Value == valueBInput.Value; } else if (Operator == Comparison.Greater) { output.Value = valueAInput.Value > valueBInput.Value; } else if (Operator == Comparison.Less) { output.Value = valueAInput.Value < valueBInput.Value; } }; valueAInput.OnAfterChanged += updateHandler; valueBInput.OnAfterChanged += updateHandler; updateHandler(); }
private void ReleaseEntry(ZooKeeperConnectionInfo connectionInfo, ConnectionEntry entry, bool remove) { bool shouldDispose; lock (this.PoolLock) { if (remove) { this.Connections.As <ICollection <KeyValuePair <ZooKeeperConnectionInfo, ConnectionEntry> > >() .Remove(new KeyValuePair <ZooKeeperConnectionInfo, ConnectionEntry>(connectionInfo, entry)); } shouldDispose = --entry.UserCount == 0; // this guarantee is upheld by the fact that we include the timeout watcher task as a "user" Invariant.Require( !shouldDispose || !(this.Connections.TryGetValue(connectionInfo, out var registeredEntry) && registeredEntry == entry), "If we're disposing then the entry must be removed from the pool" ); } if (shouldDispose) { // kick off connection disposal in the background to // avoid blocking/throwing and to handle the case where the task hasn't yet completed entry.ConnectionTask.ContinueWith( t => { var ignored = t.Result.DisposeAsync(); }, TaskContinuationOptions.OnlyOnRanToCompletion ); } }
protected override void OnSetup(IBehaviourContext context) { var rerollInput = Reroll[context]; ConnectionEntry <int> minInput = Min[context]; ConnectionEntry <int> maxInput = Max[context]; ConnectionEntry <int> output = Output[context]; float roll = 0.0f; Action outputHandlder = () => { output.Value = Mathf.RoundToInt(Mathf.Lerp(minInput.Value, maxInput.Value, roll)); }; Action rerollHandler = () => { roll = UnityEngine.Random.Range(0.0f, 1.0f); outputHandlder(); }; rerollInput.OnEventFired += rerollHandler; minInput.OnAfterChanged += outputHandlder; maxInput.OnAfterChanged += outputHandlder; rerollHandler(); }
private void CloseConnection(ConnectionEntry entry) { NetGraph graph = entry.Graph; lock (entry) { if (!graph.IsDisposed) { ConnectionHistoryEntry history = new ConnectionHistoryEntry(graph.NetworkDescription, graph.Uuid, graph.Created, DateTime.Now); bool noConnections = false; foreach (KeyValuePair <string, object> pair in graph.ConnectionProperties) { if (pair.Value.GetType().IsSerializable) { history.Properties[pair.Key] = pair.Value; } } try { entry.Dispose(); } catch { // Shouldn't throw but just in case } lock (_history) { _history.Add(history); } lock (_connections) { _connections.Remove(entry); if (_connections.Count == 0) { noConnections = true; } } if (CloseConnectionEvent != null) { CloseConnectionEvent(this, new ConnectionEventArgs(graph)); } if (_logger != null) { _logger.LogVerbose(CANAPE.Net.Properties.Resources.NetworkServiceBase_ConnectionClosed, graph.NetworkDescription); } if ((_state == (int)ServiceState.StopPending) && noConnections) { CompleteStop(); } } } }
public Task <ZooKeeperConnection> ConnectAsync(ZooKeeperConnectionInfo connectionInfo, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); lock (this.PoolLock) { // if we have an entry in the pool, use that if (this.Connections.TryGetValue(connectionInfo, out var entry)) { ++entry.UserCount; return(ToResultAsync(entry)); } // create a new connection var newConnectionTask = this.InternalConnectAsync(connectionInfo); var newEntry = new ConnectionEntry(newConnectionTask) { // 2 because we have both the current request and the timeout task we're about to create UserCount = 2 }; this.Connections.Add(connectionInfo, newEntry); newConnectionTask.ContinueWith(OnConnectionTaskCompleted); return(ToResultAsync(newEntry)); void OnConnectionTaskCompleted(Task <InternalConnection> internalConnectionTask) { // if we never connected, just release our hold on the task if (internalConnectionTask.Status != TaskStatus.RanToCompletion) { this.ReleaseEntry(connectionInfo, newEntry, remove: true); } // Otherwise, wait until either max age has elapsed or the connection is lost to release our hold. This // ensures both that the connection won't be removed from the pool prematurely as well as that it will be // eventually removed even if it stops being used else { Task.Delay(this._maxAge.TimeSpan, internalConnectionTask.Result.ConnectionLostToken) .ContinueWith(_ => this.ReleaseEntry(connectionInfo, newEntry, remove: true)); } } } async Task <ZooKeeperConnection> ToResultAsync(ConnectionEntry entry) { try { var internalConnection = await entry.ConnectionTask.ConfigureAwait(false); return(new ZooKeeperConnection(internalConnection, releaseToPool: () => this.ReleaseEntry(connectionInfo, entry, remove: false))); } catch { // if we fail to construct a connection, still release our hold on the entry to allow cleanup this.ReleaseEntry(connectionInfo, entry, remove: false); throw; } } }
/// <summary> /// Close a connection /// </summary> /// <param name="graph">The graph to close</param> public void CloseConnection(NetGraph graph) { ConnectionEntry entry = GetConnection(graph); if (entry != null) { CloseConnection(entry); } }
public DataSourceConnection(Env env, DataSource ds, string user, string pass) { super(env); _conn = new ConnectionEntry(env); _conn.init(ds, user, pass); connectInternal(env, null, user, pass, null, -1, null, 0, null, null, false, false); }
private async ValueTask <Connection> GetConnectionAsync(SiloAddress endpoint) { ImmutableArray <Connection> result; ConnectionEntry entry = default; var acquiredConnectionLock = false; try { // Lock the entry to ensure it will not be removed while the connectio attempt is occuring. while (!acquiredConnectionLock) { entry = GetOrCreateEntry(endpoint, ref acquiredConnectionLock); if (entry.Connections.Length >= this.connectionOptions.ConnectionsPerEndpoint) { result = entry.Connections; break; } ThrowIfRecentFailure(endpoint, entry); // Wait a short time before reattempting to acquire the lock await Task.Delay(10); } // Attempt to connect. Connection connection = default; var now = DateTime.UtcNow; try { connection = await this.ConnectAsync(endpoint); entry = OnConnectedInternal(endpoint, connection); result = entry.Connections; } catch (Exception exception) { OnConnectionFailed(endpoint, now); throw new ConnectionFailedException( $"Unable to connect to endpoint {endpoint}. See {nameof(exception.InnerException)}", exception); } } finally { if (acquiredConnectionLock) { entry.ReleaseLock(); } } nextConnection = (nextConnection + 1) % result.Length; return(result[nextConnection]); }
/// <summary> /// Set a timeout on a connection /// </summary> /// <param name="graph">The graph to set the timeout on</param> /// <param name="timeout">The timeout value in milliseconds</param> /// <param name="afterdata">True to timeout after last data received, otherwise absolute</param> public void SetTimeout(NetGraph graph, int timeout, bool afterdata) { ConnectionEntry entry = GetConnection(graph); if (entry != null) { lock (entry) { entry.SetTimeout(timeout, afterdata); } } }
/** * Set the current underlying connection and * corresponding information: host, port and * database name. * * @param host server host * @param port server port * @param dbname database name */ protected bool connectInternal(Env env, string host, string userName, string password, string dbname, int port, string socket, int flags, string driver, string url, bool isNewLink, bool isEmulatePrepares) { if (_conn != null) { throw new IllegalStateException(getClass().getSimpleName() + " attempt to open multiple connections"); } _host = host; _userName = userName; _password = password; _port = port; _socket = socket; _flags = flags; _driver = driver; _url = url; _isEmulatePrepares = isEmulatePrepares; if (dbname == null) { dbname = ""; } _catalog = dbname; _conn = connectImpl(env, host, userName, password, dbname, port, socket, flags, driver, url, isNewLink, isEmulatePrepares); if (_conn != null) { try { if ("".equals(_catalog)) { _catalog = _conn.getConnection().getCatalog(); } } catch (SQLException e) { log.log(Level.FINE, e.ToString(), e); } } return(_conn != null && _conn.getConnection() != null); }
private void _comboBoxGoogleUser_SelectedIndexChanged(object sender, EventArgs e) { ConnectionEntry storedCredential = _googleCredentials.Credentials .Where(z => String.Compare(z.Name, (_comboBoxGoogleUser.SelectedItem as ConnectionEntry).Name) == 0) .FirstOrDefault(); if (storedCredential != null) { this._settingsToEdit.UserKey = this._comboBoxGoogleUser.Text = storedCredential.UserKey; UpdateAPIKeyFromCredentials(_settingsToEdit); } }
private ConnectionEntry OnConnectedInternal(SiloAddress address, Connection connection) { bool acquiredConnectionLock = false; ConnectionEntry entry = default; lock (this.collectionLock) { try { entry = this.GetOrCreateEntry(address, ref acquiredConnectionLock); var newConnections = entry.Connections.Contains(connection) ? entry.Connections : entry.Connections.Add(connection); return(this.connections[address] = entry.WithConnections(newConnections).WithLastFailure(default));
/** * Closes the connection. */ protected void close() { // php/1418 // cleanup(); ConnectionEntry conn = _conn; _conn = null; if (conn != null) { conn.phpClose(); } }
protected override void OnSetup(IBehaviourContext context) { ConnectionEntry <bool> valueAInput = ValueA[context]; ConnectionEntry <bool> output = Output[context]; Action updateHandler = () => { output.Value = !valueAInput.Value; }; valueAInput.OnAfterChanged += updateHandler; updateHandler(); }
internal void Initialize(ConnectionEntry<ComputationConnection<double>>[] inputs, ConnectionEntry<ComputationConnection<double>>[] outputs) { InputConnectionEntries = ReadOnlyArray.Wrap((from e in inputs let bc = e.Connection as IBackwardConnection where bc != null select new BackwardConnectionEntry(e.Index, bc)).ToArray()); OutputConnectionEntries = ReadOnlyArray.Wrap((from e in outputs let bc = e.Connection as IBackwardConnection where bc != null select new BackwardConnectionEntry(e.Index, bc)).ToArray()); Initialized(); }
/// <summary>Called when a client connects to the http server</summary> /// <param name="sender">The socket listener reporting the new connection</param> /// <param name="arguments">Contains the socket of the connecting client</param> private void clientConnected(object sender, SocketEventArgs arguments) { ClientConnection clientConnection; // An exception from the AcceptClientConnection method would end up in the // ThreadPool. In .NET 2.0, the behavior in this case is clearly defined // (ThreadPool prints exception to console and ignores it), but since this // would leave the client running into the timeout, we try to at least // shut down the socket gracefully and to pester the developer try { clientConnection = AcceptClientConnection(arguments.Socket); } catch (Exception exception) { System.Diagnostics.Trace.WriteLine( "AcceptClientConnection() threw an exception, dropping connection" ); System.Diagnostics.Trace.WriteLine( "Exception from AcceptClientConnection(): " + exception.ToString() ); System.Diagnostics.Trace.Assert( false, "AcceptClientConnection() threw an exception, connection will be dropped" ); // Send 500 internal server error here! try { arguments.Socket.Shutdown(SocketShutdown.Both); } finally { arguments.Socket.Close(); } throw; } try { ConnectionEntry entry = new ConnectionEntry(clientConnection); lock (this.clientCleanupQueue) { this.clientCleanupQueue.Enqueue(DateTime.UtcNow, entry); } lock (this.connectedClients) { this.connectedClients.Add(clientConnection, entry); } } catch (Exception) { clientConnection.Drop(); throw; } }
protected override void OnSetup(IBehaviourContext context) { object fieldInputObject = Field.GetConnectionObject(context); // Debug.Log (fieldInputObject); ConnectionEntry fieldInput = (ConnectionEntry)fieldInputObject; EventEntry onChangedOutput = onChanged[context]; Action eventHandler = () => { onChangedOutput.Invoke(); }; fieldInput.OnAfterChanged += eventHandler; }
private ConnectionEntry OnConnectedInternal(SiloAddress address, Connection connection) { bool acquiredConnectionLock = false; ConnectionEntry entry = default; lock (this.collectionLock) { try { entry = this.GetOrCreateEntry(address, ref acquiredConnectionLock); // Do not add a connection multiple times. if (entry.Connections.Contains(connection)) { return(entry); } return(this.connections[address] = entry.WithConnections(entry.Connections.Add(connection)).WithLastFailure(default));
protected override void OnSetup(IBehaviourContext context) { ConnectionEntry <int> valueInput = Value[context]; ConnectionEntry <int> minInput = Min[context]; ConnectionEntry <int> maxInput = Max[context]; ConnectionEntry <int> output = Output[context]; Action updateHandler = () => { output.Value = Mathf.Clamp(valueInput.Value, minInput.Value, maxInput.Value); }; valueInput.OnAfterChanged += updateHandler; minInput.OnAfterChanged += updateHandler; maxInput.OnAfterChanged += updateHandler; updateHandler(); }
protected override ConnectionEntry connectImpl(Env env, string host, string userName, string password, string dbname, int port, string socket, int flags, string driver, string url, bool isNewLink, bool isEmulatePrepares) { try { if (driver == null) { JdbcDriverContext driverContext = env.getQuercus().getJdbcDriverContext(); driver = driverContext.getDriver("sqlite"); } if (driver == null) { driver = "org.sqlite.JDBC"; } _driver = driver; ConnectionEntry jConn = env.getConnection(driver, url, null, null, !isNewLink); return(jConn); } catch (SQLException e) { env.warning(e); return(null); } catch (Exception e) { env.warning(e); return(null); } }
private void btnRemove_Click(object sender, EventArgs e) { var selectedItem = this._comboBoxGoogleUser.SelectedItem; if (selectedItem != null) { if (AskYesNoQuestion(this, String.Format(PluginResources.Google_DeleteConnectionQuestion, selectedItem.ToString()), PluginResources.Google_DeleteConnectionCaption) == DialogResult.Yes) { ConnectionEntry entry = selectedItem as ConnectionEntry; _googleCredentials.DeleteNamedEntry(entry.UserKey); _dataStore.Save(_googleCredentials); Settings tempSettings = new Settings("", entry.UserKey); _credentialStore.RemoveCredential(tempSettings.CredentialsUri); _comboBoxGoogleUser.Items.Remove(selectedItem); // delete from the save connections name list } } }
/// <summary> /// Gets the connections between two stations. /// </summary> /// <param name="stationFrom">The startpoint of the journey</param> /// <param name="stationTo">The endpoint of the journey</param> /// <returns>A collection of connections between two stations to display</returns> public IEnumerable <ConnectionEntry> GetConnections(string stationFrom, string stationTo) { ConnectionEntry tmpEntry; Connections connections = transport.GetConnections(stationFrom, stationTo); foreach (Connection connection in connections.ConnectionList) { tmpEntry = new ConnectionEntry { StationFrom = connection.From.Station.Name, StationTo = connection.To.Station.Name, DepartureTime = connection.From.Departure.Value.ToString("HH:mm"), ArrivalTime = connection.To.Arrival.Value.ToString("HH:mm"), Duration = connection.Duration.Substring(3, 5) }; yield return(tmpEntry); foreach (Section section in connection.Sections) { tmpEntry = new ConnectionEntry { DepartureTime = section.Departure.Departure.Value.ToString("HH:mm"), ArrivalTime = section.Arrival.Arrival.Value.ToString("HH:mm"), DepartureStation = section.Departure.Station.Name, ArrivalStation = section.Arrival.Station.Name }; if (section.Journey != null) { tmpEntry.Direction = section.Journey.To; } else { tmpEntry.Direction = ""; } yield return(tmpEntry); } } }
static void CloseEntry(ConnectionEntry ent) { try { if (ent.Client != null) { ent.Client.Close(); } if (ent.Writer != null) { ent.Writer.Dispose(); } } catch { } _clients.Remove(ent); }
protected override void OnSetup(IBehaviourContext context) { ConnectionEntry <bool> conditionInput = Condition[context]; EventEntry trueOutput = True[context]; EventEntry falseOutput = False[context]; Action eventHandler = () => { if (conditionInput.Value) { trueOutput.Invoke(); } else { falseOutput.Invoke(); } }; conditionInput.OnAfterChanged += eventHandler; }
public void GetEntry_ParsesEachColumn() { var provider = CreateProvider(); var row = CreateDataRow(); row["ConnectionString"] = "CustomConnectionString"; row["ConnectionOp"] = "new SqlConnection()"; row["Context"] = "StackTrace"; var entry = provider.GetEntry(row); var expected = new ConnectionEntry { CustomConnectionStringName = "Custom", Text = "new SqlConnection()", StackTrace = "StackTrace" }; var printer = new Stateprinter(); Assert.AreEqual(printer.PrintObject(expected), printer.PrintObject(entry)); }
/** * Sets the catalog */ public void setCatalog(Env env, string name) { if (_catalog != null && _catalog.equals(name)) { return; } clearErrors(); // php/142v // mysql jdbc: can't reuse old statements after a USE query _savedStmt = null; _freeStmt = null; if (!_isUsed && _isCatalogOptimEnabled) { // The database @is only connected, but not used, reopen with // a real catalog ConnectionEntry conn = _conn; _conn = null; if (conn != null) { conn.phpClose(); } connectInternal(env, _host, _userName, _password, name, _port, _socket, _flags, _driver, _url, false, _isEmulatePrepares); } else { _conn.setCatalog(name); } _catalog = name; }
protected override void OnSetup(IBehaviourContext context) { ConnectionEntry <int> firesInput = Fires[context]; var perSecondsInput = PerSeconds[context]; var spacingInput = Spacing[context]; var eventInput = Event[context]; var limitedtOutput = Limited[context]; var FiringTimes = new Queue <float>(); float lastFiringTime = float.MinValue; eventInput.OnEventFired += () => { if (Time.time < lastFiringTime + spacingInput.Value) { return; } if (FiringTimes.Count < firesInput.Value) { FiringTimes.Enqueue(Time.time); lastFiringTime = Time.time; limitedtOutput.Invoke(); } else { float lastTime = FiringTimes.Peek(); if (Time.time > lastTime + perSecondsInput.Value) { FiringTimes.Dequeue(); FiringTimes.Enqueue(Time.time); lastFiringTime = Time.time; limitedtOutput.Invoke(); } } }; }
private void OnConnectionFailed(SiloAddress address, DateTime lastFailure) { bool acquiredConnectionLock = false; ConnectionEntry entry = default; lock (this.collectionLock) { try { entry = this.GetOrCreateEntry(address, ref acquiredConnectionLock); if (entry.LastFailure.HasValue) { var ticks = Math.Max(lastFailure.Ticks, entry.LastFailure.Value.Ticks); lastFailure = new DateTime(ticks); } // Clean up defunct connections var connections = entry.Connections; foreach (var c in connections) { if (!c.IsValid) { connections = connections.Remove(c); } } this.connections[address] = entry.WithLastFailure(lastFailure).WithConnections(connections); } finally { if (acquiredConnectionLock) { entry.ReleaseLock(); } } } }
/// <summary>Called when a client connects to the http server</summary> /// <param name="sender">The socket listener reporting the new connection</param> /// <param name="arguments">Contains the socket of the connecting client</param> private void clientConnected(object sender, SocketEventArgs arguments) { ClientConnection clientConnection; // An exception from the AcceptClientConnection method would end up in the // ThreadPool. In .NET 2.0, the behavior in this case is clearly defined // (ThreadPool prints exception to console and ignores it), but since this // would leave the client running into the timeout, we try to at least // shut down the socket gracefully and to pester the developer try { clientConnection = AcceptClientConnection(arguments.Socket); } catch(Exception exception) { System.Diagnostics.Trace.WriteLine( "AcceptClientConnection() threw an exception, dropping connection" ); System.Diagnostics.Trace.WriteLine( "Exception from AcceptClientConnection(): " + exception.ToString() ); System.Diagnostics.Trace.Assert( false, "AcceptClientConnection() threw an exception, connection will be dropped" ); // Send 500 internal server error here! try { arguments.Socket.Shutdown(SocketShutdown.Both); } finally { arguments.Socket.Close(); } throw; } try { ConnectionEntry entry = new ConnectionEntry(clientConnection); lock(this.clientCleanupQueue) { this.clientCleanupQueue.Enqueue(DateTime.UtcNow, entry); } lock(this.connectedClients) { this.connectedClients.Add(clientConnection, entry); } } catch(Exception) { clientConnection.Drop(); throw; } }
/// <param name="sessionID">The session this new ConnectionID will belong to</param> /// <returns>The new ConnectionID allocated</returns> public string AllocateNewConnectionID(string sessionID) { ASSERT( !string.IsNullOrEmpty(sessionID), "Missing parameter 'sessionID'" ); LOG( "AllocateNewConnectionID(" + sessionID + ") - Start" ); bool sessionAllocated = false; string connectionID; lock( LockObject ) { LOG( "AllocateNewConnectionID(" + sessionID + ") - Lock aquired" ); CheckValidity(); SessionEntry sessionEntry; if(! AllSessions.TryGetValue(sessionID, out sessionEntry) ) { LOG( "AllocateNewConnectionID(" + sessionID + ") - This is the first connection in the sesion ; Allocating a new SessionEntry" ); sessionEntry = new SessionEntry(); AllSessions.Add( sessionID, sessionEntry ); sessionAllocated = true; } var otherConnectionIDsInSession = sessionEntry.ConnectionIDs.ToArray(); connectionID = Guid.NewGuid().ToString(); var connectionEntry = new ConnectionEntry( this, sessionID, connectionID ); AllConnections.Add( connectionID, connectionEntry ); sessionEntry.ConnectionIDs.Add( connectionID ); LOG( "AllocateNewConnectionID(" + sessionID + ") - Starting DisconnectionTimeout" ); connectionEntry.DisconnectionTimeout = TasksQueue.CreateTask( 0, 0, 0, DisconnectionSeconds, 0, (taskEntry)=>{ConnectionEntry_DisconnectionTimeout(taskEntry, connectionEntry);} ); LOG( "AllocateNewConnectionID(" + sessionID + ") - Started DisconnectionTimeout " + connectionEntry.DisconnectionTimeout ); // Reset all other connections that are in the same session than this connection // => So, if the user just changed its page, the connection of the old page is reset // and if the user has more than 1 page, the other pages will simply reconnect. LOG( "RegisterConnection(" + connectionID + ") - Resetting " + otherConnectionIDsInSession.Length + " connections in the same SessionID" ); foreach( var otherConnectionID in otherConnectionIDsInSession ) { bool connectionExists; SendMessagesToConnectionIfAvailable( otherConnectionID, new Message[]{}, out connectionExists ); } CheckValidity(); LOG( "AllocateNewConnectionID(" + sessionID + ") - Exit: " + connectionID ); } ConnectionAllocatedInvokeCallbacks( connectionID ); if( sessionAllocated ) SessionAllocatedInvokeCallbacks( sessionID ); return connectionID; }
private void ConnectionEntry_DisconnectionTimeout(CommonLibs.Utils.Tasks.TaskEntry taskEntry, ConnectionEntry connectionEntry) { LOG( "ConnectionEntry_DisconnectionTimeout() - Start" ); var customObjects = new List<object>(); string connectionID; lock( LockObject ) { ASSERT( taskEntry != null, "Missing parameter 'taskEntry'" ); ASSERT( connectionEntry != null, "Missing parameter 'connectionEntry'" ); if( (connectionEntry.DisconnectionTimeout == null) || (connectionEntry.DisconnectionTimeout.ID != taskEntry.ID) ) { LOG( "*** The state of the ConnectionEntry changed between the trigger of the timeout and the Locker.EnterWriteLock() in this method" ); // ^^ Chances this happens are very low. This is more a sign of something wrong is going on. // This timeout trigger is not valid anymore => discard it return; } LOG( "ConnectionEntry_DisconnectionTimeout('" + taskEntry + "', " + connectionEntry.ConnectionID + ") - Lock aquired" ); // Discard the TaskEntry that just triggered //connectionEntry.DisconnectionTimeout.Dispose(); <= Don't dispose it, it is still running, it's this one!!! connectionEntry.DisconnectionTimeout = null; connectionID = connectionEntry.ConnectionID; var sessionID = connectionEntry.SessionID; ASSERT( !string.IsNullOrEmpty(connectionID), "'connectionEntry.ConnectionID' is missing" ); ASSERT( !string.IsNullOrEmpty(sessionID), "'connectionEntry.SessionID' is missing" ); CheckValidity(); ASSERT( AllConnections.ContainsKey(connectionID), "This ConnectionEntry is not handled by this ConnectionList" ); ASSERT( connectionEntry.Connection == null, "We are supposed to declare a long-polling HTTP connection definately disconnected. An active Connection is not supposed to be present here" ); // This connection is considered definately lost => Remove it from 'AllSessions' ... SessionEntry sessionEntry; if(! AllSessions.TryGetValue(sessionID, out sessionEntry) ) { FAIL( "The connection '" + connectionID + "' is reqested to be removed but SessionID '" + sessionID + "' is not in 'AllSessions'" ); } else { if(! sessionEntry.ConnectionIDs.Remove(connectionID) ) FAIL( "The connection '" + connectionID + "' is reqested to be removed but is not in 'AllSessions'" ); } // ... and from 'AllConnections' ... if(! AllConnections.Remove(connectionID) ) { FAIL( "The connection '" + connectionID + "' is reqested to be removed but is not in 'AllConnections'" ); } // ... and Dispose() it. customObjects.AddRange( connectionEntry.CustomObjects.Select(v=>v.Value) ); connectionEntry.Dispose(); CheckValidity(); LOG( "ConnectionEntry_DisconnectionTimeout('" + taskEntry + "', " + connectionEntry.ConnectionID + ") - Release lock" ); } // Fire ConnectionLost event ConnectionLostInvokeCallbacks( connectionID ); // Dispose CustomObjects that are IDisposable if( customObjects != null ) { foreach( var obj in customObjects ) { var disposable = obj as IDisposable; if( disposable != null ) { try { disposable.Dispose(); } catch(System.Exception ex) { FAIL( "'disposable.Dispose()' threw an exception (" + ex.GetType().FullName + "): " + ex.Message ); } } } } LOG( "ConnectionEntry_DisconnectionTimeout('" + taskEntry + "', " + connectionEntry.ConnectionID + ") - Exit" ); }
private void ConnectionEntry_StaleTimeout(CommonLibs.Utils.Tasks.TaskEntry taskEntry, ConnectionEntry connectionEntry) { LOG( "ConnectionEntry_StaleTimeout() - Start" ); var messagesToSend = new List<KeyValuePair<IConnection,RootMessage>>(); lock( LockObject ) { ASSERT( connectionEntry != null, "Missing parameter 'connectionEntry'" ); if( (connectionEntry.StaleTimeout == null) || (connectionEntry.StaleTimeout.ID != taskEntry.ID) ) { LOG( "*** The state of the ConnectionEntry changed between the trigger of the timeout and the Locker.EnterWriteLock() in this method" ); // ^^ Chances this happens are very low. This is more a sign of something wrong is going on. // This timeout trigger is not valid anymore => discard it return; } LOG( "ConnectionEntry_StaleTimeout('" + taskEntry + "', " + connectionEntry.ConnectionID + ") - Lock aquired" ); // Discard the TaskEntry that just triggered //connectionEntry.StaleTimeout.Dispose(); <= Don't dispose it, it is still running, it's this one!!! connectionEntry.StaleTimeout = null; var connectionID = connectionEntry.ConnectionID; var sessionID = connectionEntry.SessionID; ASSERT( !string.IsNullOrEmpty(connectionID), "'connectionEntry.ConnectionID' is missing" ); ASSERT( !string.IsNullOrEmpty(sessionID), "'connectionEntry.SessionID' is missing" ); CheckValidity(); ASSERT( AllConnections.ContainsKey(connectionID), "This ConnectionEntry is not handled by this ConnectionList" ); ASSERT( connectionEntry.Connection != null, "We are supposed to declare a long-polling HTTP connection stale. An active Connection is supposed to be present here" ); // Ask the peer to reconnect messagesToSend.Add( new KeyValuePair<IConnection,RootMessage>(connectionEntry.Connection, RootMessage.CreateResetRootMessage()) ); connectionEntry.Connection = null; // Start the DisconnectionTimeout LOG( "ConnectionEntry_StaleTimeout('" + taskEntry + "', " + connectionEntry.ConnectionID + ") - Creating DisconnectionTimeout" ); connectionEntry.DisconnectionTimeout = TasksQueue.CreateTask( 0, 0, 0, DisconnectionSeconds, 0, (taskEntryParm)=>{ConnectionEntry_DisconnectionTimeout(taskEntryParm, connectionEntry);} ); LOG( "ConnectionEntry_StaleTimeout('" + taskEntry + "', " + connectionEntry.ConnectionID + ") - Created DisconnectionTimeout " + connectionEntry.DisconnectionTimeout ); CheckValidity(); LOG( "ConnectionEntry_StaleTimeout('" + taskEntry + "', " + connectionEntry.ConnectionID + ") - Exit" ); } // Send messages (NB: must be outside any lock()s ) foreach( var pair in messagesToSend ) pair.Key.SendResponseMessage( pair.Value ); }
private void CloseConnection(ConnectionEntry entry) { NetGraph graph = entry.Graph; lock (entry) { if (!graph.IsDisposed) { ConnectionHistoryEntry history = new ConnectionHistoryEntry(graph.NetworkDescription, graph.Uuid, graph.Created, DateTime.Now); bool noConnections = false; foreach (KeyValuePair<string, object> pair in graph.ConnectionProperties) { if (pair.Value.GetType().IsSerializable) { history.Properties[pair.Key] = pair.Value; } } try { entry.Dispose(); } catch { // Shouldn't throw but just in case } lock (_history) { _history.Add(history); } lock (_connections) { _connections.Remove(entry); if (_connections.Count == 0) { noConnections = true; } } if (CloseConnectionEvent != null) { CloseConnectionEvent(this, new ConnectionEventArgs(graph)); } if (_logger != null) { _logger.LogVerbose(CANAPE.Net.Properties.Resources.NetworkServiceBase_ConnectionClosed, graph.NetworkDescription); } if ((_state == (int)ServiceState.StopPending) && noConnections) { CompleteStop(); } } } }
protected async Task ConnectionService(ConnectionEntry service) { var dtc = service.Connection; var ptc = service.Protocol; var batch = new RequestQueue.Batch(); do { // when queue was empty at the call moment, wait for batch to receive requests. if (!_queue.Dequeue(batch)) await batch; try { // serializes requests in batch with proper formatting into connection DataStorage. ptc.CreateRequest(batch.GetRequests()); // sends data content with proper connection level framing when needed. await dtc.SendAsync(); // setup protocol state(and connection if needed) to process response stream. ptc.BeginResponse(); // protocol ParseResponse will return true when no more data is needed from the connection. do await dtc.ReadAsync(); while (!ptc.ParseResponse()); } finally { // will close resource handles and report/complete remaining requests. ptc.EndResponse(); // some of the requests in the batch may be one way or "quiet" response model. batch.CompleteRemaining(); } } while (dtc.KeepAlive); // close the connection gracefully when service is stopped. await dtc.CloseAsync(false); }
protected async Task AddConnectionService() { var resetOpenGate = true; var service = new ConnectionEntry { Connection = CreateConnection(EndPoint) }; try { // trying to open new connection. await service.Connection.ConnectAsync(); service.Protocol = CreateProtocol(service.Connection); ConnectionAdded(service); _openingConnection = resetOpenGate = false; // schedule async service on connection. await ConnectionService(service); } catch (Exception fault) { var dtc = service.Connection; ConnectionFailed(fault, service, resetOpenGate); var nowait = dtc.CloseAsync(true); } }
private bool ConnectionFailed(Exception ex, ConnectionEntry entry, bool wasOpening) { var lockTacken = false; var retry_connection = false; var fail_waiting = false; try { _lock.Enter(ref lockTacken); // double linked list remove method... if (entry == _tail) if (entry == _head) _head = _tail = null; else { _tail = entry._prev; _tail._next = null; } else if (entry == _head) { _head = entry._next; _head._prev = null; } else { var prev = entry._prev; var next = entry._next; prev._next = next; next._prev = prev; } // schedule connection failure responses. if (wasOpening) { // report all queued requests as failed when first activating connection attempt fail. if (_activeWorkers == 0) fail_waiting = true; // extra new connections may simply fail due to remote resource provisioning, no action needed. _openingConnection = false; } else { // when all active connections fail and queue is not empty, will try to open new connection to revive link. if (--_activeWorkers == 0 && _queue.QueuedCount > 0) retry_connection = true; } } finally { if (lockTacken) _lock.Exit(); } // we may need to retry opening link connection or fail or waiting requests. if (retry_connection) QueueConnectionService(true); if (fail_waiting) _queue.FailQueued(); return false; }
private ConnectionEntry ConnectionAdded(ConnectionEntry entry) { var lockTacken = false; try { _lock.Enter(ref lockTacken); // double linked list add-to-tail method. if (_tail == null) _tail = _head = entry; else { _tail._next = entry; entry._prev = _tail; _tail = entry; } // update tracking stats on channel. entry.InitialPosition = _activeWorkers++; _lastIssued = Environment.TickCount; } finally { if (lockTacken) _lock.Exit(); } return entry; }