예제 #1
0
        // used for testing to (carefully!) allow two clients in the same process
        internal void StartInternal()
        {
            transport.Start();
            LogManager.MyIPEndPoint  = transport.MyAddress.Endpoint; // transport.MyAddress is only set after transport is Started.
            CurrentActivationAddress = ActivationAddress.NewActivationAddress(transport.MyAddress, handshakeClientId);
            ClientStatistics         = new ClientStatisticsManager(config);

            listeningCts = new CancellationTokenSource();
            var ct = listeningCts.Token;

            listenForMessages = true;

            // Keeping this thread handling it very simple for now. Just queue task on thread pool.
            Task.Factory.StartNew(() =>
            {
                try
                {
                    RunClientMessagePump(ct);
                }
                catch (Exception exc)
                {
                    logger.Error(ErrorCode.Runtime_Error_100326, "RunClientMessagePump has thrown exception", exc);
                }
            }
                                  );
            grainInterfaceMap = transport.GetTypeCodeMap(grainFactory).Result;

            ClientStatistics.Start(statisticsProviderManager, transport, clientId)
            .WaitWithThrow(initTimeout);

            StreamingInitialize();
        }
예제 #2
0
        public OutsideRuntimeClient(
            ILoggerFactory loggerFactory,
            IOptions <ClientMessagingOptions> clientMessagingOptions,
            IOptions <TypeManagementOptions> typeManagementOptions,
            IOptions <StatisticsOptions> statisticsOptions,
            ApplicationRequestsStatisticsGroup appRequestStatistics,
            StageAnalysisStatisticsGroup schedulerStageStatistics,
            ClientStatisticsManager clientStatisticsManager,
            MessagingTrace messagingTrace)
        {
            this.loggerFactory            = loggerFactory;
            this.statisticsOptions        = statisticsOptions;
            this.appRequestStatistics     = appRequestStatistics;
            this.schedulerStageStatistics = schedulerStageStatistics;
            this.ClientStatistics         = clientStatisticsManager;
            this.messagingTrace           = messagingTrace;
            this.logger            = loggerFactory.CreateLogger <OutsideRuntimeClient>();
            this.handshakeClientId = GrainId.NewClientId();
            callbacks = new ConcurrentDictionary <CorrelationId, CallbackData>();
            this.clientMessagingOptions = clientMessagingOptions.Value;
            this.typeMapRefreshInterval = typeManagementOptions.Value.TypeMapRefreshInterval;

            this.sharedCallbackData = new SharedCallbackData(
                msg => this.UnregisterCallback(msg.Id),
                this.loggerFactory.CreateLogger <CallbackData>(),
                this.clientMessagingOptions,
                this.appRequestStatistics,
                this.clientMessagingOptions.ResponseTimeout);
        }
예제 #3
0
        public void Dispose()
        {
            if (this.disposing)
            {
                return;
            }
            this.disposing = true;

            Utils.SafeExecute(() => this.callbackTimer?.Dispose());
            Utils.SafeExecute(() =>
            {
                if (typeMapRefreshTimer != null)
                {
                    typeMapRefreshTimer.Dispose();
                    typeMapRefreshTimer = null;
                }
            });

            if (listeningCts != null)
            {
                Utils.SafeExecute(() => listeningCts.Dispose());
                listeningCts = null;
            }

            Utils.SafeExecute(() => transport?.Dispose());
            if (ClientStatistics != null)
            {
                Utils.SafeExecute(() => ClientStatistics.Dispose());
                ClientStatistics = null;
            }

            Utils.SafeExecute(() => (this.ServiceProvider as IDisposable)?.Dispose());
            this.ServiceProvider = null;
            GC.SuppressFinalize(this);
        }
예제 #4
0
        public void Dispose()
        {
            if (this.disposing)
            {
                return;
            }
            this.disposing = true;

            if (listeningCts != null)
            {
                Utils.SafeExecute(() => listeningCts.Dispose());
                listeningCts = null;
            }

            Utils.SafeExecute(() => this.assemblyProcessor?.Dispose());

            Utils.SafeExecute(() => transport?.Dispose());
            if (ClientStatistics != null)
            {
                Utils.SafeExecute(() => ClientStatistics.Dispose());
                ClientStatistics = null;
            }

            Utils.SafeExecute(() => (this.ServiceProvider as IDisposable)?.Dispose());
            this.ServiceProvider = null;
            GC.SuppressFinalize(this);
        }
예제 #5
0
        public void Dispose()
        {
            if (this.disposing)
            {
                return;
            }
            this.disposing = true;

            Utils.SafeExecute(() => this.callbackTimer?.Dispose());
            Utils.SafeExecute(() =>
            {
                if (typeMapRefreshTimer != null)
                {
                    typeMapRefreshTimer.Dispose();
                    typeMapRefreshTimer = null;
                }
            });

            Utils.SafeExecute(() => transport?.Dispose());
            if (ClientStatistics != null)
            {
                Utils.SafeExecute(() => ClientStatistics.Dispose());
                ClientStatistics = null;
            }

            Utils.SafeExecute(() => (this.ServiceProvider as IDisposable)?.Dispose());

            Utils.SafeExecute(() => this.ClusterConnectionLost = null);
            Utils.SafeExecute(() => this.GatewayCountChanged   = null);
            Utils.SafeExecute(() => this.ClientInvokeCallback  = null);

            this.ServiceProvider = null;
            GC.SuppressFinalize(this);
        }
예제 #6
0
        public void Dispose()
        {
            if (listeningCts != null)
            {
                listeningCts.Dispose();
                listeningCts = null;
            }

            transport.Dispose();
            if (ClientStatistics != null)
            {
                ClientStatistics.Dispose();
                ClientStatistics = null;
            }
            GC.SuppressFinalize(this);
        }
예제 #7
0
        public void Dispose()
        {
            if (listeningCts != null)
            {
                listeningCts.Dispose();
                listeningCts = null;

                this.assemblyProcessor?.Dispose();
            }

            transport?.Dispose();
            if (ClientStatistics != null)
            {
                ClientStatistics.Dispose();
                ClientStatistics = null;
            }

            (this.ServiceProvider as IDisposable)?.Dispose();
            this.ServiceProvider = null;
            GC.SuppressFinalize(this);
        }
예제 #8
0
        internal void ConsumeServices(IServiceProvider services)
        {
            try
            {
                AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;

                this.ServiceProvider = services;

                var connectionLostHandlers = this.ServiceProvider.GetServices <ConnectionToClusterLostHandler>();
                foreach (var handler in connectionLostHandlers)
                {
                    this.ClusterConnectionLost += handler;
                }

                var clientInvokeCallbacks = this.ServiceProvider.GetServices <ClientInvokeCallback>();
                foreach (var handler in clientInvokeCallbacks)
                {
                    this.ClientInvokeCallback += handler;
                }

                this.InternalGrainFactory = this.ServiceProvider.GetRequiredService <IInternalGrainFactory>();
                this.ClientStatistics     = this.ServiceProvider.GetRequiredService <ClientStatisticsManager>();
                this.messageFactory       = this.ServiceProvider.GetService <MessageFactory>();

                var serializationManager = this.ServiceProvider.GetRequiredService <SerializationManager>();
                this.localObjects = new InvokableObjectManager(
                    this,
                    serializationManager,
                    this.loggerFactory.CreateLogger <InvokableObjectManager>());

                this.sharedCallbackData = new SharedCallbackData(
                    this.TryResendMessage,
                    msg => this.UnregisterCallback(msg.Id),
                    this.loggerFactory.CreateLogger <CallbackData>(),
                    this.clientMessagingOptions,
                    serializationManager,
                    this.appRequestStatistics);
                var timerLogger = this.loggerFactory.CreateLogger <SafeTimer>();
                var minTicks    = Math.Min(this.clientMessagingOptions.ResponseTimeout.Ticks, TimeSpan.FromSeconds(1).Ticks);
                var period      = TimeSpan.FromTicks(minTicks);
                this.callbackTimer = new SafeTimer(timerLogger, this.OnCallbackExpiryTick, null, period, period);

                this.GrainReferenceRuntime = this.ServiceProvider.GetRequiredService <IGrainReferenceRuntime>();

                BufferPool.InitGlobalBufferPool(this.clientMessagingOptions);

                this.clientProviderRuntime = this.ServiceProvider.GetRequiredService <ClientProviderRuntime>();

                this.localAddress = ConfigUtilities.GetLocalIPAddress(this.clientMessagingOptions.PreferredFamily, this.clientMessagingOptions.NetworkInterfaceName);

                // Client init / sign-on message
                logger.Info(ErrorCode.ClientInitializing, string.Format(
                                "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}",
                                BARS, Dns.GetHostName(), localAddress, handshakeClientId));
                string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}",
                                                BARS, RuntimeVersion.Current, PrintAppDomainDetails());
                logger.Info(ErrorCode.ClientStarting, startMsg);

                if (TestOnlyThrowExceptionDuringInit)
                {
                    throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit");
                }

                this.gatewayListProvider = this.ServiceProvider.GetRequiredService <IGatewayListProvider>();

                var statisticsLevel = statisticsOptions.Value.CollectionLevel;
                if (statisticsLevel.CollectThreadTimeTrackingStats())
                {
                    incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver", this.loggerFactory, this.statisticsOptions, this.schedulerStageStatistics);
                }
            }
            catch (Exception exc)
            {
                if (logger != null)
                {
                    logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc);
                }
                ConstructorReset();
                throw;
            }
        }
예제 #9
0
        internal void ConsumeServices(IServiceProvider services)
        {
            this.ServiceProvider = services;

            var connectionLostHandlers = this.ServiceProvider.GetServices <ConnectionToClusterLostHandler>();

            foreach (var handler in connectionLostHandlers)
            {
                this.ClusterConnectionLost += handler;
            }

            var clientInvokeCallbacks = this.ServiceProvider.GetServices <ClientInvokeCallback>();

            foreach (var handler in clientInvokeCallbacks)
            {
                this.ClientInvokeCallback += handler;
            }

            this.InternalGrainFactory = this.ServiceProvider.GetRequiredService <IInternalGrainFactory>();
            this.ClientStatistics     = this.ServiceProvider.GetRequiredService <ClientStatisticsManager>();
            this.serializationManager = this.ServiceProvider.GetRequiredService <SerializationManager>();
            this.messageFactory       = this.ServiceProvider.GetService <MessageFactory>();

            this.GrainReferenceRuntime = this.ServiceProvider.GetRequiredService <IGrainReferenceRuntime>();

            var statisticsOptions = this.ServiceProvider.GetRequiredService <IOptions <ClientStatisticsOptions> >().Value;

            StatisticsCollector.Initialize(statisticsOptions.CollectionLevel);

            BufferPool.InitGlobalBufferPool(this.clientMessagingOptions);

            try
            {
                AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;

                clientProviderRuntime = this.ServiceProvider.GetRequiredService <ClientProviderRuntime>();

                this.localAddress = ConfigUtilities.GetLocalIPAddress(this.clientMessagingOptions.PreferredFamily, this.clientMessagingOptions.NetworkInterfaceName);

                // Client init / sign-on message
                logger.Info(ErrorCode.ClientInitializing, string.Format(
                                "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}",
                                BARS, Dns.GetHostName(), localAddress, handshakeClientId));
                string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}",
                                                BARS, RuntimeVersion.Current, PrintAppDomainDetails());
                logger.Info(ErrorCode.ClientStarting, startMsg);

                if (TestOnlyThrowExceptionDuringInit)
                {
                    throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit");
                }

                this.gatewayListProvider = this.ServiceProvider.GetRequiredService <IGatewayListProvider>();

                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver", this.loggerFactory);
                }
            }
            catch (Exception exc)
            {
                if (logger != null)
                {
                    logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc);
                }
                ConstructorReset();
                throw;
            }
        }
예제 #10
0
        internal void ConsumeServices(IServiceProvider services)
        {
            this.ServiceProvider = services;

            var connectionLostHandlers = services.GetServices <ConnectionToClusterLostHandler>();

            foreach (var handler in connectionLostHandlers)
            {
                this.ClusterConnectionLost += handler;
            }

            var clientInvokeCallbacks = services.GetServices <ClientInvokeCallback>();

            foreach (var handler in clientInvokeCallbacks)
            {
                this.ClientInvokeCallback += handler;
            }

            this.InternalGrainFactory = this.ServiceProvider.GetRequiredService <IInternalGrainFactory>();
            this.ClientStatistics     = this.ServiceProvider.GetRequiredService <ClientStatisticsManager>();
            this.SerializationManager = this.ServiceProvider.GetRequiredService <SerializationManager>();
            this.messageFactory       = this.ServiceProvider.GetService <MessageFactory>();

            this.config = services.GetRequiredService <ClientConfiguration>();
            this.GrainReferenceRuntime = this.ServiceProvider.GetRequiredService <IGrainReferenceRuntime>();

            if (!LogManager.IsInitialized)
            {
                LogManager.Initialize(config);
            }
            StatisticsCollector.Initialize(config);
            this.assemblyProcessor = this.ServiceProvider.GetRequiredService <AssemblyProcessor>();
            this.assemblyProcessor.Initialize();

            logger         = LogManager.GetLogger("OutsideRuntimeClient", LoggerType.Runtime);
            this.AppLogger = LogManager.GetLogger("Application", LoggerType.Application);

            BufferPool.InitGlobalBufferPool(config);


            try
            {
                LoadAdditionalAssemblies();

                if (!UnobservedExceptionsHandlerClass.TrySetUnobservedExceptionHandler(UnhandledException))
                {
                    logger.Warn(ErrorCode.Runtime_Error_100153, "Unable to set unobserved exception handler because it was already set.");
                }

                AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;

                clientProviderRuntime     = this.ServiceProvider.GetRequiredService <ClientProviderRuntime>();
                statisticsProviderManager = new StatisticsProviderManager("Statistics", clientProviderRuntime);
                var statsProviderName = statisticsProviderManager.LoadProvider(config.ProviderConfigurations)
                                        .WaitForResultWithThrow(initTimeout);
                if (statsProviderName != null)
                {
                    config.StatisticsProviderName = statsProviderName;
                }

                responseTimeout   = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout;
                this.localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface);

                // Client init / sign-on message
                logger.Info(ErrorCode.ClientInitializing, string.Format(
                                "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}",
                                BARS, config.DNSHostName, localAddress, handshakeClientId));
                string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}",
                                                BARS, RuntimeVersion.Current, PrintAppDomainDetails());
                startMsg = string.Format("{0} Config= " + Environment.NewLine + " {1}", startMsg, config);
                logger.Info(ErrorCode.ClientStarting, startMsg);

                if (TestOnlyThrowExceptionDuringInit)
                {
                    throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit");
                }

                this.gatewayListProvider = this.ServiceProvider.GetRequiredService <IGatewayListProvider>();
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver");
                }
            }
            catch (Exception exc)
            {
                if (logger != null)
                {
                    logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc);
                }
                ConstructorReset();
                throw;
            }
        }
예제 #11
0
        internal void ConsumeServices(IServiceProvider services)
        {
            this.ServiceProvider = services;

            var connectionLostHandlers = this.ServiceProvider.GetServices <ConnectionToClusterLostHandler>();

            foreach (var handler in connectionLostHandlers)
            {
                this.ClusterConnectionLost += handler;
            }

            var clientInvokeCallbacks = this.ServiceProvider.GetServices <ClientInvokeCallback>();

            foreach (var handler in clientInvokeCallbacks)
            {
                this.ClientInvokeCallback += handler;
            }

            this.InternalGrainFactory = this.ServiceProvider.GetRequiredService <IInternalGrainFactory>();
            this.ClientStatistics     = this.ServiceProvider.GetRequiredService <ClientStatisticsManager>();
            this.SerializationManager = this.ServiceProvider.GetRequiredService <SerializationManager>();
            this.messageFactory       = this.ServiceProvider.GetService <MessageFactory>();

            this.config = this.ServiceProvider.GetRequiredService <ClientConfiguration>();

            var resolvedClientMessagingOptions = this.ServiceProvider.GetRequiredService <IOptions <ClientMessagingOptions> >();

            this.clientMessagingOptions = resolvedClientMessagingOptions.Value;

            this.GrainReferenceRuntime = this.ServiceProvider.GetRequiredService <IGrainReferenceRuntime>();

            this.ServiceProvider.GetService <TelemetryManager>()?.AddFromConfiguration(this.ServiceProvider, config.TelemetryConfiguration);

            var statisticsOptions = this.ServiceProvider.GetRequiredService <IOptions <StatisticsOptions> >();

            StatisticsCollector.Initialize(statisticsOptions.Value.CollectionLevel);

            BufferPool.InitGlobalBufferPool(resolvedClientMessagingOptions);

            try
            {
                AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;

                clientProviderRuntime     = this.ServiceProvider.GetRequiredService <ClientProviderRuntime>();
                statisticsProviderManager = this.ServiceProvider.GetRequiredService <StatisticsProviderManager>();
                var statsProviderName = statisticsProviderManager.LoadProvider(config.ProviderConfigurations)
                                        .WaitForResultWithThrow(initTimeout);
                if (statsProviderName != null)
                {
                    statisticsOptions.Value.ProviderName = statsProviderName;
                }

                responseTimeout   = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout;
                this.localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface);

                // Client init / sign-on message
                logger.Info(ErrorCode.ClientInitializing, string.Format(
                                "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}",
                                BARS, config.DNSHostName, localAddress, handshakeClientId));
                string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}",
                                                BARS, RuntimeVersion.Current, PrintAppDomainDetails());
                startMsg = string.Format("{0} Config= " + Environment.NewLine + " {1}", startMsg, config);
                logger.Info(ErrorCode.ClientStarting, startMsg);

                if (TestOnlyThrowExceptionDuringInit)
                {
                    throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit");
                }

                this.gatewayListProvider = this.ServiceProvider.GetRequiredService <IGatewayListProvider>();

                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver", this.loggerFactory);
                }
            }
            catch (Exception exc)
            {
                if (logger != null)
                {
                    logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc);
                }
                ConstructorReset();
                throw;
            }
        }
예제 #12
0
        public OutsideRuntimeClient(ClientConfiguration cfg, bool secondary = false)
        {
            if (cfg == null)
            {
                Console.WriteLine("An attempt to create an OutsideRuntimeClient with null ClientConfiguration object.");
                throw new ArgumentException("OutsideRuntimeClient was attempted to be created with null ClientConfiguration object.", "cfg");
            }

            var services = new ServiceCollection();

            services.AddSingleton(cfg);
            services.AddSingleton <TypeMetadataCache>();
            services.AddSingleton <AssemblyProcessor>();
            services.AddSingleton(this);
            services.AddSingleton <IRuntimeClient>(this);
            services.AddSingleton <GrainFactory>();
            services.AddFromExisting <IGrainFactory, GrainFactory>();
            services.AddFromExisting <IInternalGrainFactory, GrainFactory>();
            services.AddFromExisting <IGrainReferenceConverter, GrainFactory>();
            services.AddSingleton <ClientProviderRuntime>();
            services.AddFromExisting <IMessagingConfiguration, ClientConfiguration>();
            services.AddSingleton <IGatewayListProvider>(
                sp => ActivatorUtilities.CreateInstance <GatewayProviderFactory>(sp).CreateGatewayListProvider());
            services.AddSingleton <SerializationManager>();
            services.AddSingleton <MessageFactory>();
            services.AddSingleton <Func <string, Logger> >(LogManager.GetLogger);
            services.AddSingleton <StreamProviderManager>();
            services.AddSingleton <ClientStatisticsManager>();
            services.AddFromExisting <IStreamProviderManager, StreamProviderManager>();
            services.AddSingleton <CodeGeneratorManager>();

            this.ServiceProvider = services.BuildServiceProvider();

            this.InternalGrainFactory = this.ServiceProvider.GetRequiredService <IInternalGrainFactory>();
            this.ClientStatistics     = this.ServiceProvider.GetRequiredService <ClientStatisticsManager>();
            this.SerializationManager = this.ServiceProvider.GetRequiredService <SerializationManager>();
            this.messageFactory       = this.ServiceProvider.GetService <MessageFactory>();

            this.config = cfg;

            if (!LogManager.IsInitialized)
            {
                LogManager.Initialize(config);
            }
            StatisticsCollector.Initialize(config);
            this.assemblyProcessor = this.ServiceProvider.GetRequiredService <AssemblyProcessor>();
            this.assemblyProcessor.Initialize();

            logger    = LogManager.GetLogger("OutsideRuntimeClient", LoggerType.Runtime);
            appLogger = LogManager.GetLogger("Application", LoggerType.Application);

            BufferPool.InitGlobalBufferPool(config);
            this.handshakeClientId = GrainId.NewClientId();

            tryResendMessage   = TryResendMessage;
            unregisterCallback = msg => UnRegisterCallback(msg.Id);

            try
            {
                LoadAdditionalAssemblies();

                callbacks    = new ConcurrentDictionary <CorrelationId, CallbackData>();
                localObjects = new ConcurrentDictionary <GuidId, LocalObjectData>();

                if (!secondary)
                {
                    UnobservedExceptionsHandlerClass.SetUnobservedExceptionHandler(UnhandledException);
                }
                AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;

                clientProviderRuntime     = this.ServiceProvider.GetRequiredService <ClientProviderRuntime>();
                statisticsProviderManager = new StatisticsProviderManager("Statistics", clientProviderRuntime);
                var statsProviderName = statisticsProviderManager.LoadProvider(config.ProviderConfigurations)
                                        .WaitForResultWithThrow(initTimeout);
                if (statsProviderName != null)
                {
                    config.StatisticsProviderName = statsProviderName;
                }

                responseTimeout = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout;
                var localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface);

                // Client init / sign-on message
                logger.Info(ErrorCode.ClientInitializing, string.Format(
                                "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}",
                                BARS, config.DNSHostName, localAddress, handshakeClientId));
                string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}",
                                                BARS, RuntimeVersion.Current, PrintAppDomainDetails());
                startMsg = string.Format("{0} Config= " + Environment.NewLine + " {1}", startMsg, config);
                logger.Info(ErrorCode.ClientStarting, startMsg);

                if (TestOnlyThrowExceptionDuringInit)
                {
                    throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit");
                }

                config.CheckGatewayProviderSettings();

                var generation          = -SiloAddress.AllocateNewGeneration(); // Client generations are negative
                var gatewayListProvider = this.ServiceProvider.GetRequiredService <IGatewayListProvider>();
                gatewayListProvider.InitializeGatewayListProvider(cfg, LogManager.GetLogger(gatewayListProvider.GetType().Name))
                .WaitWithThrow(initTimeout);
                transport = ActivatorUtilities.CreateInstance <ProxiedMessageCenter>(this.ServiceProvider, localAddress, generation, handshakeClientId);

                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver");
                }
            }
            catch (Exception exc)
            {
                if (logger != null)
                {
                    logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc);
                }
                ConstructorReset();
                throw;
            }
        }