/// <summary> /// Initialize the grain client. This should be already done by <see cref="Deploy()"/> or <see cref="DeployAsync"/> /// </summary> public void InitializeClient() { WriteLog("Initializing Cluster Client"); this.InternalClient = (IInternalClusterClient)TestClusterHostFactory.CreateClusterClient("MainClient", this.ConfigurationSources); this.InternalClient.Connect().GetAwaiter().GetResult(); }
public static async Task Main(string[] args) { if (args.Length < 2) { Console.Error.WriteLine("Expected JSON-serialized configuration to be provided as an argument"); } var monitorProcessId = int.Parse(args[0], NumberStyles.Integer, CultureInfo.InvariantCulture); var serializedConfiguration = args[1]; var configuration = TestClusterHostFactory.DeserializeConfiguration(serializedConfiguration); var name = configuration["SiloName"]; var host = TestClusterHostFactory.CreateSiloHost(name, configuration); var cts = new CancellationTokenSource(); Console.CancelKeyPress += (sender, eventArgs) => cts.Cancel(); ListenForShutdownCommand(cts); MonitorParentProcess(monitorProcessId); await host.StartAsync(cts.Token); // This is a special marker line. var localSiloDetails = (ILocalSiloDetails)host.Services.GetService(typeof(ILocalSiloDetails)); Console.WriteLine($"{SiloAddressLog}{localSiloDetails.SiloAddress.ToParsableString()}"); Console.WriteLine($"{GatewayAddressLog}{localSiloDetails.GatewayAddress.ToParsableString()}"); Console.WriteLine(StartedLog); await cts.Token.WhenCancelled(); await host.StopAsync(CancellationToken.None); }
/// <summary>Creates and initializes a silo in the current app domain.</summary> /// <param name="appDomainName">Name of this silo.</param> /// <param name="serializedConfigurationSources">Silo config data to be used for this silo.</param> public AppDomainSiloHost(string appDomainName, string serializedConfigurationSources) { var deserializedSources = TestClusterHostFactory.DeserializeConfigurationSources(serializedConfigurationSources); this.host = TestClusterHostFactory.CreateSiloHost(appDomainName, deserializedSources); this.AppDomainTestHook = new AppDomainTestHooks(this.host); }
/// <summary> /// Initialize the grain client. This should be already done by <see cref="Deploy()"/> or <see cref="DeployAsync"/> /// </summary> public void InitializeClient() { WriteLog("Initializing Cluster Client"); this.InternalClient = (IInternalClusterClient)TestClusterHostFactory.CreateClusterClient("MainClient", this.ConfigurationSources); this.InternalClient.Connect().GetAwaiter().GetResult(); this.SerializationManager = this.ServiceProvider.GetRequiredService <SerializationManager>(); }
/// <summary>Creates and initializes a silo in the current app domain.</summary> /// <param name="appDomainName">Name of this silo.</param> /// <param name="serializedConfigurationSources">Silo config data to be used for this silo.</param> public AppDomainSiloHost(string appDomainName, string serializedConfigurationSources) { // Force TLS 1.2. It should be done by TestUtils.CheckForAzureStorage and TestUtils.CheckForEventHub, // but they will not have any effect here since this silo will run on a different AppDomain ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var deserializedSources = TestClusterHostFactory.DeserializeConfigurationSources(serializedConfigurationSources); this.host = TestClusterHostFactory.CreateSiloHost(appDomainName, deserializedSources); }
private static Task <SiloHandle> Create( string siloName, IList <IConfigurationSource> configurationSources, Assembly[] assemblies) { var configBuilder = new ConfigurationBuilder(); foreach (var source in configurationSources) { configBuilder.Add(source); } var configuration = configBuilder.Build(); var applicationBase = configuration[nameof(TestClusterOptions.ApplicationBaseDirectory)]; AppDomainSetup setup = GetAppDomainSetupInfo(applicationBase); var appDomain = AppDomain.CreateDomain(siloName, null, setup); try { var asms = (assemblies ?? Array.Empty <Assembly>()).Select(asm => asm.GetName().Name).ToArray(); var serializedHostConfiguration = TestClusterHostFactory.SerializeConfigurationSources(configurationSources); var args = new object[] { siloName, serializedHostConfiguration, asms }; var siloHost = (AppDomainSiloHost)appDomain.CreateInstanceAndUnwrap( typeof(AppDomainSiloHost).Assembly.FullName, typeof(AppDomainSiloHost).FullName, false, BindingFlags.Default, null, args, CultureInfo.CurrentCulture, new object[] { }); appDomain.UnhandledException += ReportUnobservedException; siloHost.Start(); SiloHandle retValue = new AppDomainSiloHandle { Name = siloName, SiloHost = siloHost, SiloAddress = siloHost.SiloAddress, GatewayAddress = siloHost.GatewayAddress, AppDomain = appDomain, }; return(Task.FromResult(retValue)); } catch (Exception) { UnloadAppDomain(appDomain); throw; } }
/// <summary>Creates a new silo in a remote app domain and returns a handle to it.</summary> public static SiloHandle Create( string siloName, IList <IConfigurationSource> configurationSources) { var configBuilder = new ConfigurationBuilder(); foreach (var source in configurationSources) { configBuilder.Add(source); } var configuration = configBuilder.Build(); var applicationBase = configuration[nameof(TestClusterOptions.ApplicationBaseDirectory)]; AppDomainSetup setup = GetAppDomainSetupInfo(applicationBase); var appDomain = AppDomain.CreateDomain(siloName, null, setup); try { var serializedHostConfiguration = TestClusterHostFactory.SerializeConfigurationSources(configurationSources); var args = new object[] { siloName, serializedHostConfiguration }; var siloHost = (AppDomainSiloHost)appDomain.CreateInstanceAndUnwrap( typeof(AppDomainSiloHost).Assembly.FullName, typeof(AppDomainSiloHost).FullName, false, BindingFlags.Default, null, args, CultureInfo.CurrentCulture, new object[] { }); appDomain.UnhandledException += ReportUnobservedException; siloHost.Start(); var retValue = new AppDomainSiloHandle { Name = siloName, SiloHost = siloHost, SiloAddress = siloHost.SiloAddress, GatewayAddress = siloHost.GatewayAddress, AppDomain = appDomain, AppDomainTestHook = siloHost.AppDomainTestHook, }; return(retValue); } catch (Exception) { UnloadAppDomain(appDomain); throw; } }
/// <summary> /// Initialize the grain client. This should be already done by <see cref="Deploy()"/> or <see cref="DeployAsync"/> /// </summary> public async Task InitializeClientAsync() { WriteLog("Initializing Cluster Client"); if (ClientHost is not null) { await StopClusterClientAsync(); } this.ClientHost = TestClusterHostFactory.CreateClusterClient("MainClient", this.ConfigurationSources); await this.ClientHost.StartAsync(); }
/// <summary>Creates a new silo and returns a handle to it.</summary> /// <param name="siloName">The name for the new silo.</param> /// <param name="configurationSources"> /// The configuration sources, interpreted by <see cref="TestClusterHostFactory.CreateSiloHost"/>. /// </param> public static async Task <SiloHandle> CreateAsync( string siloName, IList <IConfigurationSource> configurationSources) { var host = TestClusterHostFactory.CreateSiloHost(siloName, configurationSources); await host.StartAsync(); var retValue = new InProcessSiloHandle { Name = siloName, SiloHost = host, SiloAddress = host.Services.GetRequiredService <ILocalSiloDetails>().SiloAddress, GatewayAddress = host.Services.GetRequiredService <ILocalSiloDetails>().GatewayAddress, }; return(retValue); }
/// <summary> /// Create a silo handle. /// </summary> /// <param name="siloName">Name of the silo.</param> /// <param name="configuration">The configuration.</param> /// <param name="postConfigureHostBuilder">An optional delegate which is invoked just prior to building the host builder.</param> /// <returns>The silo handle.</returns> public static async Task <SiloHandle> CreateAsync( string siloName, IConfiguration configuration, Action <IHostBuilder> postConfigureHostBuilder = null) { var host = await Task.Run(async() => { var result = TestClusterHostFactory.CreateSiloHost(siloName, configuration, postConfigureHostBuilder); await result.StartAsync(); return(result); }); var retValue = new InProcessSiloHandle { Name = siloName, SiloHost = host, SiloAddress = host.Services.GetRequiredService <ILocalSiloDetails>().SiloAddress, GatewayAddress = host.Services.GetRequiredService <ILocalSiloDetails>().GatewayAddress, }; return(retValue); }
public StandaloneSiloHandle(string siloName, IConfiguration configuration, string executablePath) { if (string.IsNullOrWhiteSpace(executablePath) || !File.Exists(executablePath)) { throw new ArgumentException("Must provide at least one assembly path"); } Name = siloName; // If the debugger is attached to this process, give it an opportunity to attach to the remote process. if (Debugger.IsAttached) { configuration["AttachDebugger"] = "true"; } var serializedConfiguration = TestClusterHostFactory.SerializeConfiguration(configuration); Process = new Process(); Process.StartInfo = new ProcessStartInfo(executablePath) { ArgumentList = { Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture), serializedConfiguration }, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardOutput = true, RedirectStandardInput = true, WorkingDirectory = new FileInfo(executablePath).Directory.FullName, UseShellExecute = false, }; _outputBuilder = new StringBuilder(); _outputCloseEvent = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); _startedEvent = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); Process.OutputDataReceived += (s, e) => { if (e.Data == null) { _outputCloseEvent.SetResult(true); } else { // Read standard output from the process for status updates. if (!_startedEvent.Task.IsCompleted) { if (e.Data.StartsWith(StandaloneSiloHost.SiloAddressLog, StringComparison.Ordinal)) { SiloAddress = Orleans.Runtime.SiloAddress.FromParsableString(e.Data.Substring(StandaloneSiloHost.SiloAddressLog.Length)); } else if (e.Data.StartsWith(StandaloneSiloHost.GatewayAddressLog, StringComparison.Ordinal)) { GatewayAddress = Orleans.Runtime.SiloAddress.FromParsableString(e.Data.Substring(StandaloneSiloHost.GatewayAddressLog.Length)); } else if (e.Data.StartsWith(StandaloneSiloHost.StartedLog, StringComparison.Ordinal)) { _startedEvent.TrySetResult(true); } } lock (_outputBuilder) { _outputBuilder.AppendLine(e.Data); } } }; _errorBuilder = new StringBuilder(); _errorCloseEvent = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); Process.ErrorDataReceived += (s, e) => { if (e.Data == null) { _errorCloseEvent.SetResult(true); } else { lock (_errorBuilder) { _errorBuilder.AppendLine(e.Data); } } }; var selfReference = new WeakReference <StandaloneSiloHandle>(this); _processExitHandler = (o, e) => { if (selfReference.TryGetTarget(out var target)) { try { target.Process.Kill(entireProcessTree: true); } catch { } } }; AppDomain.CurrentDomain.ProcessExit += _processExitHandler; }