private static void InternalInitialize(ClientConfiguration config, OutsideRuntimeClient runtimeClient = null) { // We deliberately want to run this initialization code on .NET thread pool thread to escape any // TPL execution environment and avoid any conflicts with client's synchronization context var tcs = new TaskCompletionSource <ClientConfiguration>(); WaitCallback doInit = state => { try { if (TestOnlyNoConnect) { Trace.TraceInformation("TestOnlyNoConnect - Returning before connecting to cluster."); } else { // Finish initializing this client connection to the Orleans cluster DoInternalInitialize(config, runtimeClient); } tcs.SetResult(config); // Resolve promise } catch (Exception exc) { tcs.SetException(exc); // Break promise } }; // Queue Init call to thread pool thread ThreadPool.QueueUserWorkItem(doInit, null); CurrentConfig = tcs.Task.Result; // Wait for Init to finish }
/// <summary> /// This is the lock free version of uninitilize so we can share /// it between the public method and error paths inside initialize. /// This should only be called inside a lock(initLock) block. /// </summary> private static void InternalUninitialize() { // Update this first so IsInitialized immediately begins returning // false. Since this method should be protected externally by // a lock(initLock) we should be able to reset everything else // before the next init attempt. isFullyInitialized = false; LimitManager.UnInitialize(); if (RuntimeClient.Current != null) { try { RuntimeClient.Current.Reset(); } catch (Exception) { } RuntimeClient.Current = null; try { ClientProviderRuntime.UninitializeSingleton(); } catch (Exception) { } } outsideRuntimeClient = null; }
/// <summary> /// Initializes a new instance of the <see cref="ClusterClient"/> class. /// </summary> /// <param name="runtimeClient">The runtime client.</param> /// <param name="configuration">The client configuration.</param> /// <param name="loggerFactory">Logger factory used to create loggers</param> public ClusterClient(OutsideRuntimeClient runtimeClient, ILoggerFactory loggerFactory, IOptions <ClientMessagingOptions> clientMessagingOptions) { this.runtimeClient = runtimeClient; this.clusterClientLifecycle = new ClusterClientLifecycle(loggerFactory); //set PropagateActivityId flag from node cofnig RequestContext.PropagateActivityId = clientMessagingOptions.Value.PropagateActivityId; // register all lifecycle participants IEnumerable <ILifecycleParticipant <IClusterClientLifecycle> > lifecycleParticipants = this.ServiceProvider.GetServices <ILifecycleParticipant <IClusterClientLifecycle> >(); foreach (ILifecycleParticipant <IClusterClientLifecycle> participant in lifecycleParticipants) { participant?.Participate(clusterClientLifecycle); } // register all named lifecycle participants IKeyedServiceCollection <string, ILifecycleParticipant <IClusterClientLifecycle> > namedLifecycleParticipantCollections = this.ServiceProvider.GetService <IKeyedServiceCollection <string, ILifecycleParticipant <IClusterClientLifecycle> > >(); foreach (ILifecycleParticipant <IClusterClientLifecycle> participant in namedLifecycleParticipantCollections ?.GetServices(this.ServiceProvider) ?.Select(s => s?.GetService(this.ServiceProvider))) { participant?.Participate(clusterClientLifecycle); } }
/// <summary> /// Initializes a new instance of the <see cref="ClusterClient"/> class. /// </summary> /// <param name="serviceProvider">The service provider.</param> /// <param name="runtimeClient">The runtime client.</param> /// <param name="loggerFactory">Logger factory used to create loggers</param> /// <param name="clientMessagingOptions">Messaging parameters</param> public ClusterClient(IServiceProvider serviceProvider, OutsideRuntimeClient runtimeClient, ILoggerFactory loggerFactory, IOptions <ClientMessagingOptions> clientMessagingOptions) { ValidateSystemConfiguration(serviceProvider); _runtimeClient = runtimeClient; _logger = loggerFactory.CreateLogger <ClusterClient>(); _clusterClientLifecycle = new ClusterClientLifecycle(_logger); //set PropagateActivityId flag from node config RequestContext.PropagateActivityId |= clientMessagingOptions.Value.PropagateActivityId; // register all lifecycle participants IEnumerable <ILifecycleParticipant <IClusterClientLifecycle> > lifecycleParticipants = ServiceProvider.GetServices <ILifecycleParticipant <IClusterClientLifecycle> >(); foreach (var participant in lifecycleParticipants) { participant?.Participate(_clusterClientLifecycle); } // register all named lifecycle participants IKeyedServiceCollection <string, ILifecycleParticipant <IClusterClientLifecycle> > namedLifecycleParticipantCollections = ServiceProvider.GetService <IKeyedServiceCollection <string, ILifecycleParticipant <IClusterClientLifecycle> > >(); foreach (var participant in namedLifecycleParticipantCollections ?.GetServices(ServiceProvider) ?.Select(s => s?.GetService(ServiceProvider))) { participant?.Participate(_clusterClientLifecycle); }
/// <summary> /// Initializes client runtime from client configuration object. /// </summary> private static void DoInternalInitialize(ClientConfiguration config) { if (IsInitialized) { return; } lock (initLock) { if (!IsInitialized) { try { // this is probably overkill, but this ensures isFullyInitialized false // before we make a call that makes RuntimeClient.Current not null isFullyInitialized = false; outsideRuntimeClient = new OutsideRuntimeClient(config); // Keep reference, to avoid GC problems outsideRuntimeClient.Start(); // this needs to be the last successful step inside the lock so // IsInitialized doesn't return true until we're fully initialized isFullyInitialized = true; } catch (Exception exc) { // just make sure to fully Uninitialize what we managed to partially initialize, so we don't end up in inconsistent state and can later on re-initialize. Console.WriteLine("Initialization failed. {0}", exc); InternalUninitialize(); throw; } } } }
/// <summary> /// Initializes a new instance of the <see cref="ClusterClient"/> class. /// </summary> /// <param name="runtimeClient">The runtime client.</param> /// <param name="loggerFactory">Logger factory used to create loggers</param> /// <param name="clientMessagingOptions">Messaging parameters</param> public ClusterClient(OutsideRuntimeClient runtimeClient, ILoggerFactory loggerFactory, IOptions <ClientMessagingOptions> clientMessagingOptions) { this.runtimeClient = runtimeClient; this.logger = loggerFactory.CreateLogger <ClusterClient>(); this.clusterClientLifecycle = new ClusterClientLifecycle(loggerFactory.CreateLogger <LifecycleSubject>()); //set PropagateActivityId flag from node config RequestContext.PropagateActivityId |= clientMessagingOptions.Value.PropagateActivityId; // register all lifecycle participants IEnumerable <ILifecycleParticipant <IClusterClientLifecycle> > lifecycleParticipants = this.ServiceProvider.GetServices <ILifecycleParticipant <IClusterClientLifecycle> >(); foreach (var participant in lifecycleParticipants) { participant?.Participate(clusterClientLifecycle); } // register all named lifecycle participants IKeyedServiceCollection <string, ILifecycleParticipant <IClusterClientLifecycle> > namedLifecycleParticipantCollections = this.ServiceProvider.GetService <IKeyedServiceCollection <string, ILifecycleParticipant <IClusterClientLifecycle> > >(); foreach (var participant in namedLifecycleParticipantCollections ?.GetServices(this.ServiceProvider) ?.Select(s => s?.GetService(this.ServiceProvider))) { participant?.Participate(clusterClientLifecycle); } // It is fine for this field to be null in the case that the client is not the host. this.applicationLifetime = runtimeClient.ServiceProvider.GetService <IHostApplicationLifetime>() as ClientApplicationLifetime; }
/// <summary> /// Initializes a new instance of the <see cref="ClusterClient"/> class. /// </summary> /// <param name="runtimeClient">The runtime client.</param> /// <param name="configuration">The client configuration.</param> /// <param name="loggerFactory">Logger factory used to create loggers</param> public ClusterClient(OutsideRuntimeClient runtimeClient, ClientConfiguration configuration, ILoggerFactory loggerFactory) { this.Configuration = configuration; this.runtimeClient = runtimeClient; //set PropagateActivityId flag from node cofnig RequestContext.PropagateActivityId = configuration.PropagateActivityId; }
private static void InternalInitialize(ClientConfiguration config, OutsideRuntimeClient runtimeClient = null) { // We deliberately want to run this initialization code on .NET thread pool thread to escape any // TPL execution environment and avoid any conflicts with client's synchronization context var tcs = new TaskCompletionSource <ClientConfiguration>(); WaitCallback doInit = state => { try { if (TestOnlyNoConnect) { Trace.TraceInformation("TestOnlyNoConnect - Returning before connecting to cluster."); } else { // Finish initializing this client connection to the Orleans cluster DoInternalInitialize(config, runtimeClient); } tcs.SetResult(config); // Resolve promise } catch (Exception exc) { tcs.SetException(exc); // Break promise } }; // Queue Init call to thread pool thread ThreadPool.QueueUserWorkItem(doInit, null); try { CurrentConfig = tcs.Task.Result; // Wait for Init to finish } catch (AggregateException ae) { // Flatten the aggregate exception, which can be deeply nested. ae = ae.Flatten(); // If there is just one exception in the aggregate exception, throw that, otherwise throw the entire // flattened aggregate exception. var innerExceptions = ae.InnerExceptions; var exceptionToThrow = innerExceptions.Count == 1 ? innerExceptions[0] : ae; ExceptionDispatchInfo.Capture(exceptionToThrow).Throw(); } }
/// <summary> /// This is the lock free version of uninitilize so we can share /// it between the public method and error paths inside initialize. /// This should only be called inside a lock(initLock) block. /// </summary> private static void InternalUninitialize(bool cleanup = true) { // Update this first so IsInitialized immediately begins returning // false. Since this method should be protected externally by // a lock(initLock) we should be able to reset everything else // before the next init attempt. isFullyInitialized = false; if (RuntimeClient.Current != null) { try { RuntimeClient.Current.Reset(cleanup); } catch (Exception) { } RuntimeClient.Current = null; } outsideRuntimeClient = null; grainFactory = null; }
/// <summary> /// Initializes client runtime from client configuration object. /// </summary> private static void DoInternalInitialize(ClientConfiguration config, OutsideRuntimeClient runtimeClient = null) { if (IsInitialized) return; lock (initLock) { if (!IsInitialized) { try { // this is probably overkill, but this ensures isFullyInitialized false // before we make a call that makes RuntimeClient.Current not null isFullyInitialized = false; grainFactory = new GrainFactory(); if (runtimeClient == null) { runtimeClient = new OutsideRuntimeClient(config, grainFactory); } outsideRuntimeClient = runtimeClient; // Keep reference, to avoid GC problems outsideRuntimeClient.Start(); // this needs to be the last successful step inside the lock so // IsInitialized doesn't return true until we're fully initialized isFullyInitialized = true; } catch (Exception exc) { // just make sure to fully Uninitialize what we managed to partially initialize, so we don't end up in inconsistent state and can later on re-initialize. Console.WriteLine("Initialization failed. {0}", exc); InternalUninitialize(); throw; } } } }
private static void InternalInitialize(ClientConfiguration config, OutsideRuntimeClient runtimeClient = null) { // We deliberately want to run this initialization code on .NET thread pool thread to escape any // TPL execution environment and avoid any conflicts with client's synchronization context var tcs = new TaskCompletionSource<ClientConfiguration>(); WaitCallback doInit = state => { try { if (TestOnlyNoConnect) { Trace.TraceInformation("TestOnlyNoConnect - Returning before connecting to cluster."); } else { // Finish initializing this client connection to the Orleans cluster DoInternalInitialize(config, runtimeClient); } tcs.SetResult(config); // Resolve promise } catch (Exception exc) { tcs.SetException(exc); // Break promise } }; // Queue Init call to thread pool thread ThreadPool.QueueUserWorkItem(doInit, null); try { CurrentConfig = tcs.Task.Result; // Wait for Init to finish } catch (AggregateException ae) { // Flatten the aggregate exception, which can be deeply nested. ae = ae.Flatten(); // If there is just one exception in the aggregate exception, throw that, otherwise throw the entire // flattened aggregate exception. var innerExceptions = ae.InnerExceptions; var exceptionToThrow = innerExceptions.Count == 1 ? innerExceptions[0] : ae; ExceptionDispatchInfo.Capture(exceptionToThrow).Throw(); } }
private static void InternalInitialize(ClientConfiguration config, OutsideRuntimeClient runtimeClient = null) { // We deliberately want to run this initialization code on .NET thread pool thread to escape any // TPL execution environment and avoid any conflicts with client's synchronization context var tcs = new TaskCompletionSource<ClientConfiguration>(); WaitCallback doInit = state => { try { if (TestOnlyNoConnect) { Trace.TraceInformation("TestOnlyNoConnect - Returning before connecting to cluster."); } else { // Finish initializing this client connection to the Orleans cluster DoInternalInitialize(config, runtimeClient); } tcs.SetResult(config); // Resolve promise } catch (Exception exc) { tcs.SetException(exc); // Break promise } }; // Queue Init call to thread pool thread ThreadPool.QueueUserWorkItem(doInit, null); CurrentConfig = tcs.Task.Result; // Wait for Init to finish }
/// <summary> /// Initializes a new instance of the <see cref="ClusterClient"/> class. /// </summary> /// <param name="runtimeClient">The runtime client.</param> /// <param name="configuration">The client configuration.</param> public ClusterClient(OutsideRuntimeClient runtimeClient, ClientConfiguration configuration) { this.Configuration = configuration; this.runtimeClient = runtimeClient; }