private void Initialize() { // Basic initialization ChannelHost.Start(); hostStarted = true; channels = new Dictionary <string, TInternal>(); channelQueue = new LimitedQueue <TInternal>(maxAcceptedChannels); acceptQueue = new Queue <AsyncResult <TInternal, object> >(); waitQueue = new Queue <AsyncResult <bool, object> >(); // Register the endpoint with the router. SessionHandlerInfo sessionInfo; sessionInfo = this.GetSessionHandlerInfo(); sessionMode = sessionInfo != null && sessionInfo.SessionType == typeof(DuplexSession); if (sessionMode) { ChannelHost.Router.Dispatcher.AddLogical(new MsgHandlerDelegate(OnReceive), ep, typeof(DuplexSessionMsg), false, sessionInfo); } else { ChannelHost.Router.Dispatcher.AddLogical(new MsgHandlerDelegate(OnReceive), ep, typeof(WcfEnvelopeMsg), false, sessionInfo); } // Start the background task timer arBkTimer = AsyncTimer.BeginTimer(bkTaskInterval, onBkTask, null); }
/// <summary> /// Initializes a new <see cref="GrandOutput"/>. /// </summary> /// <param name="dispatcherStrategy">Strategy to use to handle the throughput.</param> public GrandOutput( IGrandOutputDispatcherStrategy dispatcherStrategy = null ) { _clients = new List<WeakReference<GrandOutputClient>>(); _dispatcher = new EventDispatcher( dispatcherStrategy ?? new EventDispatcherBasicStrategy(), null ); CommonSink = new GrandOutputCompositeSink(); var factory = new ChannelFactory( this, _dispatcher ); _channelHost = new ChannelHost( factory, OnConfigurationReady ); _channelHost.ConfigurationClosing += OnConfigurationClosing; _bufferingChannel = new BufferingChannel( _dispatcher, factory.CommonSinkOnlyReceiver ); _nextDeadClientGarbage = DateTime.UtcNow.AddMinutes( 5 ); // TODO: Adapt this termination handling to dotnet. var h = new EventHandler( OnDomainTermination ); AppDomain.CurrentDomain.DomainUnload += h; AppDomain.CurrentDomain.ProcessExit += h; }
/// <summary> /// Internal factory initialization. /// </summary> private void Initialize() { using (TimedLock.Lock(this)) { ChannelHost.Start(); hostStarted = true; // Start the background task timer if required. bkTaskInterval = GetBackgroundTaskInterval(); if (bkTaskInterval > TimeSpan.Zero) { arBkTimer = AsyncTimer.BeginTimer(bkTaskInterval, onBkTask, null); } } }
/// <summary> /// Initializes a new <see cref="GrandOutput"/>. /// </summary> /// <param name="dispatcherStrategy">Strategy to use to handle the throughput.</param> public GrandOutput(IGrandOutputDispatcherStrategy dispatcherStrategy = null) { _clients = new List <WeakReference <GrandOutputClient> >(); _dispatcher = new EventDispatcher(dispatcherStrategy ?? new EventDispatcherBasicStrategy(), null); CommonSink = new GrandOutputCompositeSink(); var factory = new ChannelFactory(this, _dispatcher); _channelHost = new ChannelHost(factory, OnConfigurationReady); _channelHost.ConfigurationClosing += OnConfigurationClosing; _bufferingChannel = new BufferingChannel(_dispatcher, factory.CommonSinkOnlyReceiver); _nextDeadClientGarbage = DateTime.UtcNow.AddMinutes(5); // TODO: Adapt this termination handling to dotnet. var h = new EventHandler(OnDomainTermination); AppDomain.CurrentDomain.DomainUnload += h; AppDomain.CurrentDomain.ProcessExit += h; }
/// <summary> /// Internal factory cleanup. /// </summary> /// <param name="abort"><c>true</c> for a abort cleanup, <c>false</c> for normal.</param> private void Cleanup(bool abort) { Dictionary <string, TInternal> channelsCopy; using (TimedLock.Lock(this)) { if (hostStarted) { hostStarted = false; ChannelHost.Stop(); } onBkTask = null; // Stops the background task callbacks // Make a copy of the channels table and then clear the // member variable. I'm doing this so the channels will // be closed below, outside of the lock. channelsCopy = channels; channels = null; } if (channelsCopy != null) { foreach (TInternal channel in channelsCopy.Values) { try { if (abort) { channel.Abort(); } else { channel.Close(); } } catch { // Ignore errors due to channels already being closed, etc. } } } }
private void Cleanup(Exception e) { using (TimedLock.Lock(ChannelHost.SyncRoot)) { if (hostStarted) { // Remove the route from the message router. if (ChannelHost.Router != null) { ChannelHost.Router.Dispatcher.RemoveTarget(this); } hostStarted = false; ChannelHost.Stop(); } } List <LillTekChannelBase> abortChannels = null; using (TimedLock.Lock(this)) { // Terminate any pending accepts if (acceptQueue != null) { while (acceptQueue.Count > 0) { acceptQueue.Dequeue().Notify(); } acceptQueue = null; } // Terminate any pending waits if (waitQueue != null) { while (waitQueue.Count > 0) { waitQueue.Dequeue().Notify(); } waitQueue = null; } // Abort any queued accepted channels if (channelQueue != null) { while (channelQueue.Count > 0) { TInternal channel = channelQueue.Dequeue(); if (channel.State != CommunicationState.Closed) { channel.Abort(); } } channelQueue = null; } // $todo(jeff.lill): Delete this ------------------------ // Setup to abort all of the listener's channels. if (channels != null && channels.Count > 0) { abortChannels = new List <LillTekChannelBase>(channels.Count); foreach (LillTekChannelBase channel in channels.Values) { abortChannels.Add(channel); } } //--------------------------------------------------- // Stop the background task timer onBkTask = null; } // Actually abort the channels outside of the lock. if (abortChannels != null) { foreach (LillTekChannelBase channel in abortChannels) { channel.Close(); } } }
void OnConfigurationReady( ChannelHost.ConfigurationReady e ) { foreach( var channel in e.GetAllRoutes() ) { channel.Initialize(); } lock( _bufferingChannel.FlushLock ) { _bufferingChannel.FlushBuffer( e.IsEmptyConfiguration ? (Func<string,IChannel>)null : e.ObtainRoute ); e.ApplyConfiguration(); } // The new configuration is applied: we signal the clients // and use this configuration thread to clean the weak refs list if needed. if( SignalConfigurationChanged() ) { int nbDeadClients; lock( _clients ) nbDeadClients = DoGarbageDeadClients( DateTime.UtcNow ); if( nbDeadClients > 0 ) e.Monitor.SendLine( LogLevel.Info, string.Format( "Removing {0} dead client(s).", nbDeadClients ), null ); else e.Monitor.SendLine( LogLevel.Trace, "No dead client to remove.", null ); } }