internal void ReportError(string msg) { Interlocked.Increment(ref numErrors); msg = string.Format("Error Time: {0:G}\n\t{1}", TraceLogger.PrintDate(DateTime.UtcNow), msg); Console.WriteLine(msg); }
private void RegisterSiloInstance() { string partitionKey = deploymentId; string rowKey = SiloInstanceTableEntry.ConstructRowKey(siloAddress); IPEndPoint myEndpoint = siloAddress.Endpoint; myEntry = new SiloInstanceTableEntry { PartitionKey = partitionKey, RowKey = rowKey, DeploymentId = deploymentId, Address = myEndpoint.Address.ToString(), Port = myEndpoint.Port.ToString(CultureInfo.InvariantCulture), Generation = generation.ToString(CultureInfo.InvariantCulture), HostName = myEndpoint.Address.ToString(), ProxyPort = "30000", RoleName = "MyRole", InstanceName = "MyInstance", UpdateZone = "0", FaultZone = "0", StartTime = TraceLogger.PrintDate(DateTime.UtcNow), }; logger.Info("MyEntry={0}", myEntry); manager.RegisterSiloInstance(myEntry); }
private static ReminderTableEntry ConvertToTableEntry(ReminderEntry remEntry, Guid serviceId, string deploymentId) { string partitionKey = ReminderTableEntry.ConstructPartitionKey(serviceId, remEntry.GrainRef); string rowKey = ReminderTableEntry.ConstructRowKey(remEntry.GrainRef, remEntry.ReminderName); string serviceIdStr = ReminderTableEntry.ConstructServiceIdStr(serviceId); var consistentHash = remEntry.GrainRef.GetUniformHashCode(); return(new ReminderTableEntry { PartitionKey = partitionKey, RowKey = rowKey, ServiceId = serviceIdStr, DeploymentId = deploymentId, GrainReference = remEntry.GrainRef.ToKeyString(), ReminderName = remEntry.ReminderName, StartAt = TraceLogger.PrintDate(remEntry.StartAt), Period = remEntry.Period.ToString(), GrainRefConsistentHash = String.Format("{0:X8}", consistentHash), ETag = remEntry.ETag, }); }
public Task LongCall() { int count = 0; lock (allActivationIds) { if (!allActivationIds.Contains(activationGuid)) { allActivationIds.Add(activationGuid); } count = allActivationIds.Count; } DateTime start = DateTime.UtcNow; TaskCompletionSource <bool> resolver = new TaskCompletionSource <bool>(); RegisterTimer(TimerCallback, resolver, TimeSpan.FromSeconds(2), TimeSpan.FromMilliseconds(-1)); return(resolver.Task.ContinueWith( (_) => { DateTime stop = DateTime.UtcNow; calls.Add(new Tuple <DateTime, DateTime>(start, stop)); logger.Info(((stop - start).TotalMilliseconds).ToString()); logger.Info("Start {0}, stop {1}, duration {2}. #act {3}", TraceLogger.PrintDate(start), TraceLogger.PrintDate(stop), (stop - start), count); })); }
internal string ToFullString(bool full = false) { if (!full) { return(ToString()); } List <SiloAddress> suspecters = SuspectTimes == null ? null : SuspectTimes.Select(tuple => tuple.Item1).ToList(); List <DateTime> timestamps = SuspectTimes == null ? null : SuspectTimes.Select(tuple => tuple.Item2).ToList(); return(string.Format("[SiloAddress={0} Status={1} HostName={2} ProxyPort={3} " + "RoleName={4} InstanceName={5} UpdateZone={6} FaultZone={7} StartTime = {8} IAmAliveTime = {9} {10} {11}]", SiloAddress.ToLongString(), Status, HostName, ProxyPort, RoleName, InstanceName, UpdateZone, FaultZone, TraceLogger.PrintDate(StartTime), TraceLogger.PrintDate(IAmAliveTime), suspecters == null ? "" : "Suspecters = " + Utils.EnumerableToString(suspecters, (SiloAddress sa) => sa.ToLongString()), timestamps == null ? "" : "SuspectTimes = " + Utils.EnumerableToString(timestamps, TraceLogger.PrintDate) )); }
internal void LogMessage(string message, params object[] args) { if (args.Length > 0) { message = String.Format(message, args); } message = String.Format("[{0}] {1}", TraceLogger.PrintDate(DateTime.UtcNow), message); Console.WriteLine(message); }
internal static string PrintCloudQueueMessage(CloudQueueMessage message) { return(String.Format("CloudQueueMessage: Id = {0}, NextVisibleTime = {1}, DequeueCount = {2}, PopReceipt = {3}, Content = {4}", message.Id, message.NextVisibleTime.HasValue ? TraceLogger.PrintDate(message.NextVisibleTime.Value) : "", message.DequeueCount, message.PopReceipt, message.AsString)); }
private static SiloInstanceTableEntry ConvertPartial(MembershipEntry memEntry, string deploymentId) { return(new SiloInstanceTableEntry { DeploymentId = deploymentId, IAmAliveTime = TraceLogger.PrintDate(memEntry.IAmAliveTime), PartitionKey = deploymentId, RowKey = SiloInstanceTableEntry.ConstructRowKey(memEntry.SiloAddress) }); }
public async Task StatelessWorker() { IStatelessWorkerGrain grain = GrainClient.GrainFactory.GetGrain <IStatelessWorkerGrain>(0); List <Task> promises = new List <Task>(); for (int i = 0; i < ExpectedMaxLocalActivations * 3; i++) { promises.Add(grain.LongCall()); // trigger activation of ExpectedMaxLocalActivations local activations } await Task.WhenAll(promises); await Task.Delay(2000); promises.Clear(); var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < ExpectedMaxLocalActivations * 3; i++) { promises.Add(grain.LongCall()); } await Task.WhenAll(promises); stopwatch.Stop(); //Assert.IsTrue(stopwatch.Elapsed > TimeSpan.FromSeconds(19.5), "50 requests with a 2 second processing time shouldn't take less than 20 seconds on 10 activations. But it took " + stopwatch.Elapsed); promises.Clear(); for (int i = 0; i < ExpectedMaxLocalActivations * 3; i++) { promises.Add(grain.GetCallStats()); // gather stats } await Task.WhenAll(promises); HashSet <Guid> activations = new HashSet <Guid>(); foreach (var promise in promises) { Tuple <Guid, List <Tuple <DateTime, DateTime> > > response = await(Task <Tuple <Guid, List <Tuple <DateTime, DateTime> > > >) promise; if (activations.Contains(response.Item1)) { continue; // duplicate response from the same activation } activations.Add(response.Item1); logger.Info(" {0}: Activation {1}", activations.Count, response.Item1); int count = 1; foreach (Tuple <DateTime, DateTime> call in response.Item2) { logger.Info("\t{0}: {1} - {2}", count++, TraceLogger.PrintDate(call.Item1), TraceLogger.PrintDate(call.Item2)); } } Assert.IsTrue(activations.Count <= ExpectedMaxLocalActivations, "activations.Count = " + activations.Count + " but expected no more than " + ExpectedMaxLocalActivations); }
public override string ToString() { return(string.Format("[{0}, {1}, {2}, {3}, {4}, {5}, {6}]", ReminderName, GrainRef.ToDetailedString(), period, TraceLogger.PrintDate(firstTickTime), ETag, LocalSequenceNumber, Timer == null ? "Not_ticking" : "Ticking")); }
private static SiloInstanceTableEntry Convert(MembershipEntry memEntry, string deploymentId) { var tableEntry = new SiloInstanceTableEntry { DeploymentId = deploymentId, Address = memEntry.SiloAddress.Endpoint.Address.ToString(), Port = memEntry.SiloAddress.Endpoint.Port.ToString(CultureInfo.InvariantCulture), Generation = memEntry.SiloAddress.Generation.ToString(CultureInfo.InvariantCulture), HostName = memEntry.HostName, Status = memEntry.Status.ToString(), ProxyPort = memEntry.ProxyPort.ToString(CultureInfo.InvariantCulture), RoleName = memEntry.RoleName, SiloName = memEntry.SiloName, // this is for backward compatability: in a mixed cluster of old and new version, // we need to populate both columns. InstanceName = memEntry.SiloName, UpdateZone = memEntry.UpdateZone.ToString(CultureInfo.InvariantCulture), FaultZone = memEntry.FaultZone.ToString(CultureInfo.InvariantCulture), StartTime = TraceLogger.PrintDate(memEntry.StartTime), IAmAliveTime = TraceLogger.PrintDate(memEntry.IAmAliveTime) }; if (memEntry.SuspectTimes != null) { var siloList = new StringBuilder(); var timeList = new StringBuilder(); bool first = true; foreach (var tuple in memEntry.SuspectTimes) { if (!first) { siloList.Append('|'); timeList.Append('|'); } siloList.Append(tuple.Item1.ToParsableString()); timeList.Append(TraceLogger.PrintDate(tuple.Item2)); first = false; } tableEntry.SuspectingSilos = siloList.ToString(); tableEntry.SuspectingTimes = timeList.ToString(); } else { tableEntry.SuspectingSilos = String.Empty; tableEntry.SuspectingTimes = String.Empty; } tableEntry.PartitionKey = deploymentId; tableEntry.RowKey = SiloInstanceTableEntry.ConstructRowKey(memEntry.SiloAddress); return(tableEntry); }
protected override bool PrepareMessageForSend(Message msg) { // Don't send messages that have already timed out if (msg.IsExpired) { msg.DropExpiredMessage(MessagingStatisticsGroup.Phase.Send); return(false); } // Fill in the outbound message with our silo address, if it's not already set if (!msg.ContainsHeader(Message.Header.SENDING_SILO)) { msg.SendingSilo = messageCenter.MyAddress; } // If there's no target silo set, then we shouldn't see this message; send it back if (msg.TargetSilo == null) { FailMessage(msg, "No target silo provided -- internal error"); return(false); } // If we know this silo is dead, don't bother if ((messageCenter.SiloDeadOracle != null) && messageCenter.SiloDeadOracle(msg.TargetSilo)) { FailMessage(msg, String.Format("Target {0} silo is known to be dead", msg.TargetSilo.ToLongString())); return(false); } // If we had a bad connection to this address recently, don't even try DateTime failure; if (lastConnectionFailure.TryGetValue(msg.TargetSilo, out failure)) { var since = DateTime.UtcNow.Subtract(failure); if (since < CONNECTION_RETRY_DELAY) { FailMessage(msg, String.Format("Recent ({0} ago, at {1}) connection failure trying to reach target silo {2}. Going to drop {3} msg {4} without sending. CONNECTION_RETRY_DELAY = {5}.", since, TraceLogger.PrintDate(failure), msg.TargetSilo.ToLongString(), msg.Direction, msg.Id, CONNECTION_RETRY_DELAY)); return(false); } } if (Message.WriteMessagingTraces) { msg.AddTimestamp(Message.LifecycleTag.SendOutgoing); } return(true); }
/// <summary> /// Prints the current config for a given silo. /// </summary> /// <param name="siloName">The name of the silo to print its configuration.</param> /// <returns></returns> public string ToString(string siloName) { var sb = new StringBuilder(); sb.Append("Config File Name: ").AppendLine(string.IsNullOrEmpty(SourceFile) ? "" : Path.GetFullPath(SourceFile)); sb.Append("Host: ").AppendLine(Dns.GetHostName()); sb.Append("Start time: ").AppendLine(TraceLogger.PrintDate(DateTime.UtcNow)); sb.Append("Primary node: ").AppendLine(PrimaryNode == null ? "null" : PrimaryNode.ToString()); sb.AppendLine("Platform version info:").Append(ConfigUtilities.RuntimeVersionInfo()); sb.AppendLine("Global configuration:").Append(Globals.ToString()); NodeConfiguration nc = GetConfigurationForNode(siloName); sb.AppendLine("Silo configuration:").Append(nc.ToString()); sb.AppendLine(); return(sb.ToString()); }
private static async Task <T> ExecuteWithRetriesHelper <T>( Func <int, Task <T> > function, int callCounter, int maxNumSuccessTries, int maxNumErrorTries, TimeSpan maxExecutionTime, DateTime startExecutionTime, Func <T, int, bool> retryValueFilter = null, Func <Exception, int, bool> retryExceptionFilter = null, IBackoffProvider onSuccessBackOff = null, IBackoffProvider onErrorBackOff = null) { if (maxExecutionTime != Constants.INFINITE_TIMESPAN && maxExecutionTime != default(TimeSpan)) { DateTime now = DateTime.UtcNow; if (now - startExecutionTime > maxExecutionTime) { Exception timeoutException = new TimeoutException(String.Format("ExecuteWithRetries has exceeded its max execution time of {0}. Now is {1}, started at {2}, passed {3}", maxExecutionTime, TraceLogger.PrintDate(now), TraceLogger.PrintDate(startExecutionTime), now - startExecutionTime)); throw timeoutException; } } T result = default(T); int counter = callCounter; Exception exception = null; try { callCounter++; result = await function(counter); bool retry = false; if (callCounter < maxNumSuccessTries || maxNumSuccessTries == INFINITE_RETRIES) // -1 for infinite retries { if (retryValueFilter != null) { retry = retryValueFilter(result, counter); } } if (retry) { if (onSuccessBackOff == null) { return(await ExecuteWithRetriesHelper(function, callCounter, maxNumSuccessTries, maxNumErrorTries, maxExecutionTime, startExecutionTime, retryValueFilter, retryExceptionFilter, onSuccessBackOff, onErrorBackOff)); } else { TimeSpan delay = onSuccessBackOff.Next(); await Task.Delay(delay); return(await ExecuteWithRetriesHelper(function, callCounter, maxNumSuccessTries, maxNumErrorTries, maxExecutionTime, startExecutionTime, retryValueFilter, retryExceptionFilter, onSuccessBackOff, onErrorBackOff)); } } return(result); } catch (Exception exc) { exception = exc; } if (exception != null) { bool retry = false; if (callCounter < maxNumErrorTries || maxNumErrorTries == INFINITE_RETRIES) { if (retryExceptionFilter != null) { retry = retryExceptionFilter(exception, counter); } } if (retry) { if (onErrorBackOff == null) { return(await ExecuteWithRetriesHelper(function, callCounter, maxNumSuccessTries, maxNumErrorTries, maxExecutionTime, startExecutionTime, retryValueFilter, retryExceptionFilter, onSuccessBackOff, onErrorBackOff)); } else { TimeSpan delay = onErrorBackOff.Next(); await Task.Delay(delay); return(await ExecuteWithRetriesHelper(function, callCounter, maxNumSuccessTries, maxNumErrorTries, maxExecutionTime, startExecutionTime, retryValueFilter, retryExceptionFilter, onSuccessBackOff, onErrorBackOff)); } } throw exception; } return(result); // this return value is just for the compiler to supress "not all control paths return a value". }
private static void ConvertToRow(MembershipEntry memEntry, SqlCommand command, string deploymentId) { command.Parameters.Add(new SqlParameter { ParameterName = "@deploymentid", DbType = DbType.String, Value = deploymentId }); command.Parameters.Add(new SqlParameter { ParameterName = "@address", DbType = DbType.String, Value = memEntry.SiloAddress.Endpoint.Address.ToString() }); command.Parameters.Add(new SqlParameter { ParameterName = "@port", DbType = DbType.Int32, Value = memEntry.SiloAddress.Endpoint.Port }); command.Parameters.Add(new SqlParameter { ParameterName = "@generation", DbType = DbType.Int32, Value = memEntry.SiloAddress.Generation }); command.Parameters.Add(new SqlParameter { ParameterName = "@hostname", DbType = DbType.String, Value = memEntry.HostName }); command.Parameters.Add(new SqlParameter { ParameterName = "@status", DbType = DbType.Int32, Value = memEntry.Status }); command.Parameters.Add(new SqlParameter { ParameterName = "@proxyport", DbType = DbType.Int32, Value = memEntry.ProxyPort }); command.Parameters.Add(new SqlParameter { ParameterName = "@primary", DbType = DbType.Boolean, Value = memEntry.IsPrimary }); command.Parameters.Add(new SqlParameter { ParameterName = "@rolename", DbType = DbType.String, Value = memEntry.RoleName }); command.Parameters.Add(new SqlParameter { ParameterName = "@instancename", DbType = DbType.String, Value = memEntry.InstanceName }); command.Parameters.Add(new SqlParameter { ParameterName = "@updatezone", DbType = DbType.Int32, Value = memEntry.UpdateZone }); command.Parameters.Add(new SqlParameter { ParameterName = "@faultzone", DbType = DbType.Int32, Value = memEntry.FaultZone }); command.Parameters.Add(new SqlParameter { ParameterName = "@starttime", DbType = DbType.DateTime, Value = memEntry.StartTime }); command.Parameters.Add(new SqlParameter { ParameterName = "@iamalivetime", DbType = DbType.DateTime, Value = memEntry.IAmAliveTime }); if (memEntry.SuspectTimes != null) { StringBuilder siloList = new StringBuilder(); StringBuilder timeList = new StringBuilder(); bool first = true; foreach (var tuple in memEntry.SuspectTimes) { if (!first) { siloList.Append('|'); timeList.Append('|'); } siloList.Append(tuple.Item1.ToParsableString()); timeList.Append(TraceLogger.PrintDate(tuple.Item2)); first = false; } command.Parameters.Add(new SqlParameter { ParameterName = "@suspectingsilos", DbType = DbType.String, Value = siloList.ToString() }); command.Parameters.Add(new SqlParameter { ParameterName = "@suspectingtimes", DbType = DbType.String, Value = timeList.ToString() }); } else { command.Parameters.Add(new SqlParameter { ParameterName = "@suspectingsilos", DbType = DbType.String, Value = DBNull.Value }); command.Parameters.Add(new SqlParameter { ParameterName = "@suspectingtimes", DbType = DbType.String, Value = DBNull.Value }); } }
public override string ToString() { var sb = new StringBuilder(); sb.AppendLine("Platform version info:").Append(ConfigUtilities.RuntimeVersionInfo()); sb.Append(" Host: ").AppendLine(Dns.GetHostName()); sb.Append(" Processor Count: ").Append(System.Environment.ProcessorCount).AppendLine(); sb.AppendLine("Client Configuration:"); sb.Append(" Config File Name: ").AppendLine(string.IsNullOrEmpty(SourceFile) ? "" : Path.GetFullPath(SourceFile)); sb.Append(" Start time: ").AppendLine(TraceLogger.PrintDate(DateTime.UtcNow)); sb.Append(" Gateway Provider: ").Append(GatewayProvider); if (GatewayProvider == GatewayProviderType.None) { sb.Append(". Gateway Provider that will be used instead: ").Append(GatewayProviderToUse); } sb.AppendLine(); if (Gateways != null && Gateways.Count > 0) { sb.AppendFormat(" Gateways[{0}]:", Gateways.Count).AppendLine(); foreach (var endpoint in Gateways) { sb.Append(" ").AppendLine(endpoint.ToString()); } } else { sb.Append(" Gateways: ").AppendLine("Unspecified"); } sb.Append(" Preferred Gateway Index: ").AppendLine(PreferedGatewayIndex.ToString()); if (Gateways != null && PreferedGatewayIndex >= 0 && PreferedGatewayIndex < Gateways.Count) { sb.Append(" Preferred Gateway Address: ").AppendLine(Gateways[PreferedGatewayIndex].ToString()); } sb.Append(" GatewayListRefreshPeriod: ").Append(GatewayListRefreshPeriod).AppendLine(); if (!String.IsNullOrEmpty(DeploymentId) || !String.IsNullOrEmpty(DataConnectionString)) { sb.Append(" Azure:").AppendLine(); sb.Append(" DeploymentId: ").Append(DeploymentId).AppendLine(); string dataConnectionInfo = ConfigUtilities.RedactConnectionStringInfo(DataConnectionString); // Don't print Azure account keys in log files sb.Append(" DataConnectionString: ").Append(dataConnectionInfo).AppendLine(); } if (!string.IsNullOrWhiteSpace(NetInterface)) { sb.Append(" Network Interface: ").AppendLine(NetInterface); } if (Port != 0) { sb.Append(" Network Port: ").Append(Port).AppendLine(); } sb.Append(" Preferred Address Family: ").AppendLine(PreferredFamily.ToString()); sb.Append(" DNS Host Name: ").AppendLine(DNSHostName); sb.Append(" Client Name: ").AppendLine(ClientName); sb.Append(ConfigUtilities.TraceConfigurationToString(this)); sb.Append(ConfigUtilities.IStatisticsConfigurationToString(this)); sb.Append(LimitManager); sb.AppendFormat(base.ToString()); sb.AppendFormat(" Providers:").AppendLine(); sb.Append(ProviderConfigurationUtility.PrintProviderConfigurations(ProviderConfigurations)); return(sb.ToString()); }
/// <summary> /// Initialize this Orleans silo for execution with the specified Azure deploymentId /// </summary> /// <param name="config">If null, Config data will be read from silo config file as normal, otherwise use the specified config data.</param> /// <param name="deploymentId">Azure DeploymentId this silo is running under</param> /// <param name="connectionString">Azure DataConnectionString. If null, defaults to the DataConnectionString setting from the Azure configuration for this role.</param> /// <returns><c>true</c> is the silo startup was successful</returns> public bool Start(ClusterConfiguration config, string deploymentId = null, string connectionString = null) { // Program ident Trace.TraceInformation("Starting {0} v{1}", this.GetType().FullName, RuntimeVersion.Current); // Check if deployment id was specified if (deploymentId == null) { deploymentId = serviceRuntimeWrapper.DeploymentId; } // Read endpoint info for this instance from Azure config string instanceName = serviceRuntimeWrapper.InstanceName; // Configure this Orleans silo instance if (config == null) { host = new SiloHost(instanceName); host.LoadOrleansConfig(); // Load config from file + Initializes logger configurations } else { host = new SiloHost(instanceName, config); // Use supplied config data + Initializes logger configurations } IPEndPoint myEndpoint = serviceRuntimeWrapper.GetIPEndpoint(SiloEndpointConfigurationKeyName); IPEndPoint proxyEndpoint = serviceRuntimeWrapper.GetIPEndpoint(ProxyEndpointConfigurationKeyName); host.SetSiloType(Silo.SiloType.Secondary); int generation = SiloAddress.AllocateNewGeneration(); // Bootstrap this Orleans silo instance myEntry = new SiloInstanceTableEntry { DeploymentId = deploymentId, Address = myEndpoint.Address.ToString(), Port = myEndpoint.Port.ToString(CultureInfo.InvariantCulture), Generation = generation.ToString(CultureInfo.InvariantCulture), HostName = host.Config.GetConfigurationForNode(host.Name).DNSHostName, ProxyPort = (proxyEndpoint != null ? proxyEndpoint.Port : 0).ToString(CultureInfo.InvariantCulture), RoleName = serviceRuntimeWrapper.RoleName, InstanceName = instanceName, UpdateZone = serviceRuntimeWrapper.UpdateDomain.ToString(CultureInfo.InvariantCulture), FaultZone = serviceRuntimeWrapper.FaultDomain.ToString(CultureInfo.InvariantCulture), StartTime = TraceLogger.PrintDate(DateTime.UtcNow), PartitionKey = deploymentId, RowKey = myEndpoint.Address + "-" + myEndpoint.Port + "-" + generation }; if (connectionString == null) { connectionString = serviceRuntimeWrapper.GetConfigurationSettingValue(DataConnectionConfigurationSettingName); } try { siloInstanceManager = OrleansSiloInstanceManager.GetManager( deploymentId, connectionString).WithTimeout(AzureTableDefaultPolicies.TableCreationTimeout).Result; } catch (Exception exc) { var error = String.Format("Failed to create OrleansSiloInstanceManager. This means CreateTableIfNotExist for silo instance table has failed with {0}", TraceLogger.PrintException(exc)); Trace.TraceError(error); logger.Error(ErrorCode.AzureTable_34, error, exc); throw new OrleansException(error, exc); } // Always use Azure table for membership when running silo in Azure host.SetSiloLivenessType(GlobalConfiguration.LivenessProviderType.AzureTable); if (host.Config.Globals.ReminderServiceType == GlobalConfiguration.ReminderServiceProviderType.NotSpecified || host.Config.Globals.ReminderServiceType == GlobalConfiguration.ReminderServiceProviderType.ReminderTableGrain) { host.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.AzureTable); } host.SetExpectedClusterSize(serviceRuntimeWrapper.RoleInstanceCount); siloInstanceManager.RegisterSiloInstance(myEntry); // Initialise this Orleans silo instance host.SetDeploymentId(deploymentId, connectionString); host.SetSiloEndpoint(myEndpoint, generation); host.SetProxyEndpoint(proxyEndpoint); host.InitializeOrleansSilo(); logger.Info(ErrorCode.Runtime_Error_100288, "Successfully initialized Orleans silo '{0}' as a {1} node.", host.Name, host.Type); return(StartSilo()); }