public bool TryCreateHostGroup(string name) { using (var context = _contextCreator()) { try { var service = new ZabbixApi.Services.HostGroupService(context); var hostGroup = service.GetByName(name); if (hostGroup == null) { hostGroup = new HostGroup(); hostGroup.name = name; hostGroup.Id = service.Create(hostGroup); } if (hostGroup.Id != null) { _HostGroupMetricsCache = hostGroup; return(true); } else { return(false); } } catch (Exception ex) { MetricsErrorHandler.Handle(ex, string.Format("Error on configuring zabbix host group, zabbix api {0}", _url)); return(false); } } }
public async Task <IActionResult> PutHostGroup(int id, HostGroup hostGroup) { if (id != hostGroup.Id) { return(BadRequest()); } _context.Entry(hostGroup).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!HostGroupExists(id)) { return(NotFound()); } else { throw; } } return(NoContent()); }
private ServiceHubRemoteHostClient( HostWorkspaceServices services, HubClient hubClient, HostGroup hostGroup, Stream stream) { _connectionPools = new ConnectionPools( connectionFactory: (serviceName, pool, cancellationToken) => CreateConnectionImplAsync(serviceName, callbackTarget: null, pool, cancellationToken), capacity: ConnectionPoolCapacity); // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log: services.GetService <IWorkspaceTelemetryService>()?.RegisterUnexpectedExceptionLogger(hubClient.Logger); _services = services; _hubClient = hubClient; _hostGroup = hostGroup; _endPoint = new RemoteEndPoint(stream, hubClient.Logger, incomingCallTarget: this); _endPoint.Disconnected += OnDisconnected; _endPoint.UnexpectedExceptionThrown += OnUnexpectedExceptionThrown; _endPoint.StartListening(); _assetStorage = services.GetRequiredService <ISolutionAssetStorageProvider>().AssetStorage; _serializer = services.GetRequiredService <ISerializerService>(); }
private static async Task <Stream> RequestServiceAsync( HubClient client, string serviceName, HostGroup hostGroup, TimeSpan timeout, CancellationToken cancellationToken = default) { const int max_retry = 10; const int retry_delayInMS = 50; Exception lastException = null; var descriptor = new ServiceDescriptor(serviceName) { HostGroup = hostGroup }; // call to get service can fail due to this bug - devdiv#288961 or more. // until root cause is fixed, we decide to have retry rather than fail right away for (var i = 0; i < max_retry; i++) { try { // we are wrapping HubClient.RequestServiceAsync since we can't control its internal timeout value ourselves. // we have bug opened to track the issue. // https://devdiv.visualstudio.com/DefaultCollection/DevDiv/Editor/_workitems?id=378757&fullScreen=false&_a=edit // retry on cancellation token since HubClient will throw its own cancellation token // when it couldn't connect to service hub service for some reasons // (ex, OOP process GC blocked and not responding to request) return(await RetryRemoteCallAsync <OperationCanceledException, Stream>( () => client.RequestServiceAsync(descriptor, cancellationToken), timeout, cancellationToken).ConfigureAwait(false)); } catch (RemoteInvocationException ex) { // save info only if it failed with different issue than before. if (lastException?.Message != ex.Message) { // RequestServiceAsync should never fail unless service itself is actually broken. // So far, we catched multiple issues from this NFW. so we will keep this NFW. ex.ReportServiceHubNFW("RequestServiceAsync Failed"); lastException = ex; } } // wait for retry_delayInMS before next try await Task.Delay(retry_delayInMS, cancellationToken).ConfigureAwait(false); } // crash right away to get better dump. otherwise, we will get dump from async exception // which most likely lost all valuable data FatalError.ReportUnlessCanceled(lastException); GC.KeepAlive(lastException); // unreachable throw ExceptionUtilities.Unreachable; }
public static async Task<RemoteHostClient> CreateAsync( Workspace workspace, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken)) { var primary = new HubClient("ManagedLanguage.IDE.RemoteHostClient"); var current = $"VS ({Process.GetCurrentProcess().Id})"; var hostGroup = new HostGroup(current); var remoteHostStream = await RequestServiceAsync(primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, cancellationToken).ConfigureAwait(false); var instance = new ServiceHubRemoteHostClient(workspace, primary, hostGroup, remoteHostStream); // make sure connection is done right var host = await instance._rpc.InvokeAsync<string>(WellKnownRemoteHostServices.RemoteHostService_Connect, current).ConfigureAwait(false); // TODO: change this to non fatal watson and make VS to use inproc implementation Contract.ThrowIfFalse(host == current.ToString()); instance.Connected(); // Create a workspace host to hear about workspace changes. We'll // remote those changes over to the remote side when they happen. RegisterWorkspaceHost(workspace, instance); // return instance return instance; } }
public static async Task <RemoteHostClient> CreateAsync( Workspace workspace, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken)) { // let each client to have unique id so that we can distinguish different clients when service is restarted var currentInstanceId = Interlocked.Add(ref s_instanceId, 1); var primary = new HubClient("ManagedLanguage.IDE.RemoteHostClient"); var current = $"VS ({Process.GetCurrentProcess().Id}) ({currentInstanceId})"; var hostGroup = new HostGroup(current); var timeout = TimeSpan.FromMilliseconds(workspace.Options.GetOption(RemoteHostOptions.RequestServiceTimeoutInMS)); var remoteHostStream = await RequestServiceAsync(primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, timeout, cancellationToken).ConfigureAwait(false); var instance = new ServiceHubRemoteHostClient(workspace, primary, hostGroup, remoteHostStream); // make sure connection is done right var host = await instance._rpc.InvokeAsync <string>(nameof(IRemoteHostService.Connect), current, TelemetryService.DefaultSession.SerializeSettings()).ConfigureAwait(false); // TODO: change this to non fatal watson and make VS to use inproc implementation Contract.ThrowIfFalse(host == current.ToString()); instance.Connected(); // Create a workspace host to hear about workspace changes. We'll // remote those changes over to the remote side when they happen. await RegisterWorkspaceHostAsync(workspace, instance).ConfigureAwait(false); // return instance return(instance); } }
public static async Task <RemoteHostClient> CreateAsync( Workspace workspace, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken)) { var primary = new HubClient("ManagedLanguage.IDE.RemoteHostClient"); var current = $"VS ({Process.GetCurrentProcess().Id})"; var hostGroup = new HostGroup(current); var remoteHostStream = await RequestServiceAsync(primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, cancellationToken).ConfigureAwait(false); var instance = new ServiceHubRemoteHostClient(workspace, primary, hostGroup, remoteHostStream); // make sure connection is done right var host = await instance._rpc.InvokeAsync <string>(WellKnownRemoteHostServices.RemoteHostService_Connect, current).ConfigureAwait(false); // TODO: change this to non fatal watson and make VS to use inproc implementation Contract.ThrowIfFalse(host == current.ToString()); instance.Connected(); // Create a workspace host to hear about workspace changes. We'll // remote those changes over to the remote side when they happen. RegisterWorkspaceHost(workspace, instance); // return instance return(instance); } }
protected HostGroupVM ConvertToViewModel(HostGroup entity) => new HostGroupVM { HostGroupId = entity.Id, HostGroupName = entity.Name, Hosts = entity.Hosts.Select(host => new HostVM { HostId = host.Id, HostName = host.Name, HostHeaderName = host.HeaderName, Enable = host.Enable, Week0 = host.Week0, Week1 = host.Week1, Week2 = host.Week2, Week3 = host.Week3, Week4 = host.Week4, Week5 = host.Week5, Week6 = host.Week6, }), HostSchedules = entity.HostSchedules.Select(sehedule => new HostScheduleVM { HostScheduleId = sehedule.Id, HostScheduleName = sehedule.Name, Week0 = sehedule.Week0, Week1 = sehedule.Week1, Week2 = sehedule.Week2, Week3 = sehedule.Week3, Week4 = sehedule.Week4, Week5 = sehedule.Week5, Week6 = sehedule.Week6, }) };
public async Task <Connection> ActivateAsync(CancellationToken cancellationToken) { var client = await RemoteHostClient.TryGetClientAsync(_workspace, cancellationToken).ConfigureAwait(false); if (client == null) { // There is no OOP. either user turned it off, or process got killed. // We should have already gotten a gold bar + nfw already if the OOP is missing. // so just log telemetry here so we can connect the two with session explorer. Logger.Log(FunctionId.LanguageServer_ActivateFailed, KeyValueLogMessage.NoProperty); return(null); } var hostGroup = new HostGroup(client.ClientId); var hubClient = new HubClient(ServiceHubClientName); var stream = await ServiceHubRemoteHostClient.RequestServiceAsync( _workspace, hubClient, WellKnownServiceHubServices.LanguageServer, hostGroup, cancellationToken).ConfigureAwait(false); return(new Connection(stream, stream)); }
public static async Task <RemoteHostClient> CreateAsync(HostWorkspaceServices services, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, KeyValueLogMessage.NoProperty, cancellationToken)) { Logger.Log(FunctionId.RemoteHost_Bitness, KeyValueLogMessage.Create(LogType.Trace, m => m["64bit"] = RemoteHostOptions.IsServiceHubProcess64Bit(services))); // let each client to have unique id so that we can distinguish different clients when service is restarted var clientId = $"VS ({Process.GetCurrentProcess().Id}) ({Guid.NewGuid()})"; var hostGroup = new HostGroup(clientId); var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient"); var remoteHostStream = await RequestServiceAsync(services, hubClient, WellKnownServiceHubService.RemoteHost, hostGroup, cancellationToken).ConfigureAwait(false); var client = new ServiceHubRemoteHostClient(services, hubClient, hostGroup, remoteHostStream); var uiCultureLCID = CultureInfo.CurrentUICulture.LCID; var cultureLCID = CultureInfo.CurrentCulture.LCID; // initialize the remote service await client._endPoint.InvokeAsync <string>( nameof(IRemoteHostService.InitializeGlobalState), new object?[] { uiCultureLCID, cultureLCID }, cancellationToken).ConfigureAwait(false); client.Started(); return(client); } }
private ServiceHubRemoteHostClient( HostWorkspaceServices services, HubClient hubClient, HostGroup hostGroup, Stream stream) : base(services) { var optionService = services.GetRequiredService <IOptionService>(); if (optionService.GetOption(RemoteHostOptions.EnableConnectionPool)) { int maxPoolConnection = optionService.GetOption(RemoteHostOptions.MaxPoolConnection); _connectionPool = new ConnectionPool( connectionFactory: (serviceName, cancellationToken) => CreateConnectionAsync(serviceName, callbackTarget: null, cancellationToken), maxPoolConnection); } _hubClient = hubClient; _hostGroup = hostGroup; _endPoint = new RemoteEndPoint(stream, hubClient.Logger, incomingCallTarget: this); _endPoint.Disconnected += OnDisconnected; _endPoint.UnexpectedExceptionThrown += OnUnexpectedExceptionThrown; _endPoint.StartListening(); }
public static async Task <Stream> RequestServiceAsync( Workspace workspace, HubClient client, string serviceName, HostGroup hostGroup, CancellationToken cancellationToken) { var descriptor = new ServiceDescriptor(serviceName) { HostGroup = hostGroup }; try { return(await client.RequestServiceAsync(descriptor, cancellationToken).ConfigureAwait(false)); } catch (Exception e) when(ReportNonFatalWatson(e, cancellationToken)) { // TODO: Once https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1040692. // ServiceHub may throw non-cancellation exceptions if it is called after VS started to shut down, // even if our cancellation token is signaled. Cancel the operation and do not report an error in these cases. // // If ServiceHub did not throw non-cancellation exceptions when cancellation token is signaled, // we can assume that these exceptions indicate a failure and should be reported to the user. cancellationToken.ThrowIfCancellationRequested(); RemoteHostCrashInfoBar.ShowInfoBar(workspace, e); // TODO: Propagate the original exception (see https://github.com/dotnet/roslyn/issues/40476) throw new SoftCrashException("Unexpected exception from HubClient", e, cancellationToken); }
public ActionResult DeleteConfirmed(int id) { HostGroup hostGroup = db.HostGroup.Find(id); db.HostGroup.Remove(hostGroup); db.SaveChanges(); return(RedirectToAction("Index")); }
public static async Task <Stream> RequestServiceAsync( Workspace workspace, HubClient client, string serviceName, HostGroup hostGroup, TimeSpan timeout, CancellationToken cancellationToken) { const int MaxRetryAttempts = 10; var retryDelay = TimeSpan.FromMilliseconds(50); Exception lastException = null; var descriptor = new ServiceDescriptor(serviceName) { HostGroup = hostGroup }; // Call to get service can fail due to this bug - devdiv#288961 or more. // until root cause is fixed, we decide to have retry rather than fail right away // // We have double re-try here. We have these 2 separated since 2 retries are for different problems. // First retry most likely deal with real issue on ServiceHub, second retry (cancellation) is to deal with // ServiceHub behavior we don't want to use. for (var i = 0; i < MaxRetryAttempts; i++) { try { return(await RequestServiceWithCancellationRetryAsync( workspace, client, descriptor, timeout, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) when(!(ex is OperationCanceledException)) { // save info only if it failed with different issue than before. if (lastException?.Message != ex.Message) { // RequestServiceAsync should never fail unless service itself is actually broken. // So far, we catched multiple issues from this NFW. so we will keep this NFW. ex.ReportServiceHubNFW("RequestServiceAsync Failed"); lastException = ex; } } // wait before next try await Task.Delay(retryDelay, cancellationToken).ConfigureAwait(false); } RemoteHostCrashInfoBar.ShowInfoBar(workspace, lastException); // raise soft crash exception rather than doing hard crash. // we had enough feedback from users not to crash VS on servicehub failure throw new SoftCrashException("RequestServiceAsync Failed", lastException, cancellationToken); }
/// <summary> /// Add a new <see cref="Host"/> object. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">An <see cref="ExecutedRoutedEventArgs"/> that contains the event data.</param> private void CommandBindingAddHostExecuted(object sender, ExecutedRoutedEventArgs e) { HostGroup parent = e.Parameter as HostGroup; if (this.ViewModel != null) { this.ViewModel.AddHost(parent); } }
public ActionResult Edit([Bind(Include = "groupId,groupName,groupDescription,groupIdentity")] HostGroup hostGroup) { if (ModelState.IsValid) { db.Entry(hostGroup).State = EntityState.Modified; db.SaveChanges(); return(RedirectToAction("Index")); } return(View(hostGroup)); }
public ActionResult Create([Bind(Include = "groupId,groupName,groupDescription,groupIdentity")] HostGroup hostGroup) { if (ModelState.IsValid) { db.HostGroup.Add(hostGroup); db.SaveChanges(); return(RedirectToAction("Index")); } return(View(hostGroup)); }
private ServiceHubRemoteHostClient( Workspace workspace, HubClient hubClient, HostGroup hostGroup, Stream stream) : base(workspace) { _hubClient = hubClient; _hostGroup = hostGroup; _rpc = JsonRpc.Attach(stream, target: this); // handle disconnected situation _rpc.Disconnected += OnRpcDisconnected; }
public static async Task <RemoteHostClient?> CreateAsync(Workspace workspace, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken)) { var enableConnectionPool = workspace.Options.GetOption(RemoteHostOptions.EnableConnectionPool); var maxConnection = workspace.Options.GetOption(RemoteHostOptions.MaxPoolConnection); // let each client to have unique id so that we can distinguish different clients when service is restarted var clientId = CreateClientId(Process.GetCurrentProcess().Id.ToString()); var hostGroup = new HostGroup(clientId); var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient"); // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log: WatsonReporter.InitializeLogger(hubClient.Logger); // Create the RemotableDataJsonRpc before we create the remote host: this call implicitly sets up the remote IExperimentationService so that will be available for later calls var snapshotServiceStream = await RequestServiceAsync(workspace, hubClient, WellKnownServiceHubServices.SnapshotService, hostGroup, cancellationToken).ConfigureAwait(false); var remoteHostStream = await RequestServiceAsync(workspace, hubClient, WellKnownRemoteHostServices.RemoteHostService, hostGroup, cancellationToken).ConfigureAwait(false); var remotableDataRpc = new RemotableDataJsonRpc(workspace, hubClient.Logger, snapshotServiceStream); var connectionManager = new ConnectionManager(workspace, hubClient, hostGroup, enableConnectionPool, maxConnection, new ReferenceCountedDisposable <RemotableDataJsonRpc>(remotableDataRpc)); var client = new ServiceHubRemoteHostClient(workspace, hubClient.Logger, connectionManager, remoteHostStream); var uiCultureLCID = CultureInfo.CurrentUICulture.LCID; var cultureLCID = CultureInfo.CurrentCulture.LCID; bool success = false; try { // initialize the remote service _ = await client._endPoint.InvokeAsync <string>( nameof(IRemoteHostService.Connect), new object[] { clientId, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() }, cancellationToken).ConfigureAwait(false); success = true; } finally { if (!success) { client.Dispose(); } } client.Started(); return(client); } }
private ServiceHubRemoteHostClient( Workspace workspace, HubClient hubClient, HostGroup hostGroup, Stream stream) : base(workspace) { _hubClient = hubClient; _hostGroup = hostGroup; _rpc = JsonRpc.Attach(stream, target: this); _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance); // handle disconnected situation _rpc.Disconnected += OnRpcDisconnected; }
/// <summary>Add an empty <see cref="Host"/> object instance to the current <see cref="HostFileInstance"/>.</summary> /// <param name="parent">The parent of the to be created <see cref="Host"/> object (optional, default = null).</param> /// <returns>True if a new <see cref="Host"/> object instance has been successfully added to the current <see cref="HostFileInstance"/>; otherwise false.</returns> public bool AddHost(HostGroup parent = null) { if (this.HostFileInstance != null) { if (parent != null) { return(parent.AddChildToTop(Host.CreateEmpty(parent, this.HostFileInstance.PropertyChangedCallBack))); } return(this.HostFileInstance.AddChildToTop(Host.CreateEmpty(parent, this.HostFileInstance.PropertyChangedCallBack))); } return(false); }
private static async Task <Stream> RequestServiceAsync( HubClient client, string serviceName, HostGroup hostGroup, TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken)) { const int max_retry = 10; const int retry_delayInMS = 50; Exception lastException = null; var descriptor = new ServiceDescriptor(serviceName) { HostGroup = hostGroup }; // call to get service can fail due to this bug - devdiv#288961 or more. // until root cause is fixed, we decide to have retry rather than fail right away for (var i = 0; i < max_retry; i++) { try { return(await RequestServiceAsync(client, descriptor, timeout, cancellationToken).ConfigureAwait(false)); } catch (RemoteInvocationException ex) { // save info only if it failed with different issue than before. if (lastException?.Message != ex.Message) { // RequestServiceAsync should never fail unless service itself is actually broken. // So far, we catched multiple issues from this NFW. so we will keep this NFW. WatsonReporter.Report("RequestServiceAsync Failed", ex, ReportDetailInfo); lastException = ex; } } // wait for retry_delayInMS before next try await Task.Delay(retry_delayInMS, cancellationToken).ConfigureAwait(false); } // crash right away to get better dump. otherwise, we will get dump from async exception // which most likely lost all valuable data FatalError.ReportUnlessCanceled(lastException); GC.KeepAlive(lastException); // unreachable throw ExceptionUtilities.Unreachable; }
// GET: HostGroups/Delete/5 public ActionResult Delete(int?id) { if (id == null) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest)); } HostGroup hostGroup = db.HostGroup.Find(id); if (hostGroup == null) { return(HttpNotFound()); } return(View(hostGroup)); }
public static async Task <ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace workspace, HubClient primary, TimeSpan timeout, CancellationToken cancellationToken) { ServiceHubRemoteHostClient client = null; try { // let each client to have unique id so that we can distinguish different clients when service is restarted var current = CreateClientId(Process.GetCurrentProcess().Id.ToString()); var hostGroup = new HostGroup(current); // Create the RemotableDataJsonRpc before we create the remote host: this call implicitly sets up the remote IExperimentationService so that will be available for later calls var remotableDataRpc = new RemotableDataJsonRpc( workspace, primary.Logger, await Connections.RequestServiceAsync(workspace, primary, WellKnownServiceHubServices.SnapshotService, hostGroup, timeout, cancellationToken).ConfigureAwait(false)); var remoteHostStream = await Connections.RequestServiceAsync(workspace, primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, timeout, cancellationToken).ConfigureAwait(false); var enableConnectionPool = workspace.Options.GetOption(RemoteHostOptions.EnableConnectionPool); var maxConnection = workspace.Options.GetOption(RemoteHostOptions.MaxPoolConnection); var connectionManager = new ConnectionManager(primary, hostGroup, enableConnectionPool, maxConnection, timeout, new ReferenceCountedDisposable <RemotableDataJsonRpc>(remotableDataRpc)); client = new ServiceHubRemoteHostClient(workspace, primary.Logger, connectionManager, remoteHostStream); var uiCultureLCID = CultureInfo.CurrentUICulture.LCID; var cultureLCID = CultureInfo.CurrentCulture.LCID; // make sure connection is done right var host = await client._rpc.InvokeWithCancellationAsync <string>( nameof(IRemoteHostService.Connect), new object[] { current, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() }, cancellationToken).ConfigureAwait(false); return(client); } catch (ConnectionLostException ex) { RemoteHostCrashInfoBar.ShowInfoBar(workspace, ex); Shutdown(client, ex, cancellationToken); // dont crash VS because OOP is failed to start. we will show info bar telling users to restart // but never physically crash VS. throw new SoftCrashException("Connection Lost", ex, cancellationToken); } catch (Exception ex) { Shutdown(client, ex, cancellationToken); throw; }
private async Task <Stream> GetConnectionAsync(CancellationToken cancellationToken) { // any exception from this will be caught by codelens engine and saved to log file and ignored. // this follows existing code lens behavior and user experience on failure is owned by codelens engine var hostGroupId = await _lazyCodeLensCallbackService.Value.InvokeAsync <string>( this, nameof(ICodeLensContext.GetHostGroupIdAsync), arguments : null, cancellationToken).ConfigureAwait(false); var hostGroup = new HostGroup(hostGroupId); var serviceDescriptor = new ServiceDescriptor(RoslynCodeAnalysis) { HostGroup = hostGroup }; return(await _client.RequestServiceAsync(serviceDescriptor, cancellationToken).ConfigureAwait(false)); }
private ServiceHubRemoteHostClient( Workspace workspace, HubClient hubClient, HostGroup hostGroup, Stream stream) : base(workspace) { _hubClient = hubClient; _hostGroup = hostGroup; _timeout = TimeSpan.FromMilliseconds(workspace.Options.GetOption(RemoteHostOptions.RequestServiceTimeoutInMS)); _rpc = new JsonRpc(stream, stream, target: this); _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance); // handle disconnected situation _rpc.Disconnected += OnRpcDisconnected; _rpc.StartListening(); }
private static async Task <Stream> RequestServiceAsync( HubClient client, string serviceName, HostGroup hostGroup, TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken)) { const int max_retry = 10; const int retry_delayInMS = 50; Exception lastException = null; var descriptor = new ServiceDescriptor(serviceName) { HostGroup = hostGroup }; // call to get service can fail due to this bug - devdiv#288961 or more. // until root cause is fixed, we decide to have retry rather than fail right away for (var i = 0; i < max_retry; i++) { try { return(await RequestServiceAsync(client, descriptor, timeout, cancellationToken).ConfigureAwait(false)); } catch (RemoteInvocationException ex) { // RequestServiceAsync should never fail unless service itself is actually broken. // So far, we catched multiple issues from this NFW. so we will keep this NFW. // one request from service hub team is adding service hub logs when this happen. // tracked by https://github.com/dotnet/roslyn/issues/17012 FatalError.ReportWithoutCrash(ex); lastException = ex; } // wait for retry_delayInMS before next try await Task.Delay(retry_delayInMS, cancellationToken).ConfigureAwait(false); } // crash right away to get better dump. otherwise, we will get dump from async exception // which most likely lost all valuable data FatalError.ReportUnlessCanceled(lastException); GC.KeepAlive(lastException); // unreachable throw ExceptionUtilities.Unreachable; }
public static async Task <ServiceHubRemoteHostClient> CreateWorkerAsync(Workspace workspace, HubClient primary, TimeSpan timeout, CancellationToken cancellationToken) { ServiceHubRemoteHostClient client = null; try { // let each client to have unique id so that we can distinguish different clients when service is restarted var currentInstanceId = Interlocked.Add(ref s_instanceId, 1); var current = $"VS ({Process.GetCurrentProcess().Id}) ({currentInstanceId})"; var hostGroup = new HostGroup(current); var remoteHostStream = await Connections.RequestServiceAsync(workspace, primary, WellKnownRemoteHostServices.RemoteHostService, hostGroup, timeout, cancellationToken).ConfigureAwait(false); var remotableDataRpc = new RemotableDataJsonRpc( workspace, primary.Logger, await Connections.RequestServiceAsync(workspace, primary, WellKnownServiceHubServices.SnapshotService, hostGroup, timeout, cancellationToken).ConfigureAwait(false)); var enableConnectionPool = workspace.Options.GetOption(RemoteHostOptions.EnableConnectionPool); var maxConnection = workspace.Options.GetOption(RemoteHostOptions.MaxPoolConnection); var connectionManager = new ConnectionManager(primary, hostGroup, enableConnectionPool, maxConnection, timeout, new ReferenceCountedDisposable <RemotableDataJsonRpc>(remotableDataRpc)); client = new ServiceHubRemoteHostClient(workspace, connectionManager, remoteHostStream); var uiCultureLCID = CultureInfo.CurrentUICulture.LCID; var cultureLCID = CultureInfo.CurrentCulture.LCID; // make sure connection is done right var host = await client._rpc.InvokeWithCancellationAsync <string>( nameof(IRemoteHostService.Connect), new object[] { current, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() }, cancellationToken).ConfigureAwait(false); return(client); } catch (Exception ex) { // make sure we shutdown client if initializing client has failed. client?.Shutdown(); // translate to our own cancellation if it is raised. cancellationToken.ThrowIfCancellationRequested(); // otherwise, report watson and throw original exception ex.ReportServiceHubNFW("ServiceHub creation failed"); throw; } }
public static async Task <RemoteHostClient> CreateAsync(HostWorkspaceServices services, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, KeyValueLogMessage.NoProperty, cancellationToken)) { Logger.Log(FunctionId.RemoteHost_Bitness, KeyValueLogMessage.Create(LogType.Trace, m => m["64bit"] = RemoteHostOptions.IsServiceHubProcess64Bit(services))); // let each client to have unique id so that we can distinguish different clients when service is restarted var clientId = $"VS ({Process.GetCurrentProcess().Id}) ({Guid.NewGuid()})"; var hostGroup = new HostGroup(clientId); var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient"); // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log: WatsonReporter.InitializeLogger(hubClient.Logger); var remoteHostStream = await RequestServiceAsync(services, hubClient, WellKnownServiceHubService.RemoteHost, hostGroup, cancellationToken).ConfigureAwait(false); var client = new ServiceHubRemoteHostClient(services, hubClient, hostGroup, remoteHostStream); var uiCultureLCID = CultureInfo.CurrentUICulture.LCID; var cultureLCID = CultureInfo.CurrentCulture.LCID; bool success = false; try { // initialize the remote service await client._endPoint.InvokeAsync <string>( nameof(IRemoteHostService.InitializeGlobalState), new object[] { clientId, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() }, cancellationToken).ConfigureAwait(false); success = true; } finally { if (!success) { client.Dispose(); } } client.Started(); return(client); } }
public static async Task <RemoteHostClient?> CreateAsync(Workspace workspace, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken)) { // let each client to have unique id so that we can distinguish different clients when service is restarted var clientId = CreateClientId(Process.GetCurrentProcess().Id.ToString()); var hostGroup = new HostGroup(clientId); var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient"); // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log: WatsonReporter.InitializeLogger(hubClient.Logger); var remoteHostStream = await RequestServiceAsync(workspace, hubClient, WellKnownServiceHubServices.RemoteHostService, hostGroup, cancellationToken).ConfigureAwait(false); var client = new ServiceHubRemoteHostClient(workspace, hubClient, hostGroup, remoteHostStream); var uiCultureLCID = CultureInfo.CurrentUICulture.LCID; var cultureLCID = CultureInfo.CurrentCulture.LCID; bool success = false; try { // initialize the remote service _ = await client._endPoint.InvokeAsync <string>( nameof(IRemoteHostService.Connect), new object[] { clientId, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() }, cancellationToken).ConfigureAwait(false); success = true; } finally { if (!success) { client.Dispose(); } } client.Started(); return(client); } }
private ServiceHubRemoteHostClient( HostWorkspaceServices services, HubClient hubClient, HostGroup hostGroup, Stream stream) : base(services) { _connectionPool = new ConnectionPool( connectionFactory: (serviceName, cancellationToken) => CreateConnectionAsync(serviceName, callbackTarget: null, cancellationToken), capacity: ConnectionPoolCapacity); _hubClient = hubClient; _hostGroup = hostGroup; _endPoint = new RemoteEndPoint(stream, hubClient.Logger, incomingCallTarget: this); _endPoint.Disconnected += OnDisconnected; _endPoint.UnexpectedExceptionThrown += OnUnexpectedExceptionThrown; _endPoint.StartListening(); }
/// <summary> /// Host groups to be updated. The host groups must have the groupid property defined. /// </summary> /// <param name="groups"></param> public MassUpdate(HostGroup[] groups) { this.groups = groups; }
private static async Task<Stream> RequestServiceAsync(HubClient client, string serviceName, HostGroup hostGroup, CancellationToken cancellationToken = default(CancellationToken)) { const int max_retry = 10; const int retry_delayInMS = 50; // call to get service can fail due to this bug - devdiv#288961 // until root cause is fixed, we decide to have retry rather than fail right away for (var i = 0; i < max_retry; i++) { cancellationToken.ThrowIfCancellationRequested(); try { var descriptor = new ServiceDescriptor(serviceName) { HostGroup = hostGroup }; return await client.RequestServiceAsync(descriptor, cancellationToken).ConfigureAwait(false); } catch (RemoteInvocationException ex) { // RequestServiceAsync should never fail unless service itself is actually broken. // right now, we know only 1 case where it can randomly fail. but there might be more cases so // adding non fatal watson here. FatalError.ReportWithoutCrash(ex); } // wait for retry_delayInMS before next try await Task.Delay(retry_delayInMS, cancellationToken).ConfigureAwait(false); } return Contract.FailWithReturn<Stream>("Fail to get service. look FatalError.s_reportedException for more detail"); }
/// <summary> /// </summary> /// <param name="host">Technical name of the host.</param> /// <param name="groups">Host groups to add the host to. The host groups must have the groupid property defined.</param> /// <param name="interfaces">Interfaces to be created for the host.</param> public Create(string host, HostGroup.HostGroup[] groups, HostInterface.HostInterface[] interfaces) : base(host) { this.groups = groups; this.interfaces = interfaces; }
/// <summary> /// Host groups to be updated. The host groups must have the groupid property defined. /// </summary> /// <param name="groups"></param> public MassAdd(HostGroup[] groups) { this.groups = groups; }
/// <summary>Get a <see cref="HostFile"/> object for the host file with the specified <paramref name="hostFilePath"/>.</summary> /// <param name="hostFilePath">The host file path.</param> /// <returns>An initialized <see cref="HostFile"/> object.</returns> private HostFile GetHostfile(string hostFilePath) { List<string> lines = this.DataAccess.GetHostfileContent(hostFilePath); HostFile hostFile = HostFile.CreateHostFile(hostFilePath); HostfileLineByLineNavigator navigator = new HostfileLineByLineNavigator(lines); HostfileEntryCollection collection = new HostfileEntryCollection(hostFile.PropertyChangedCallBack); foreach (HostfileLine line in navigator) { if (line.IsMultiLineComment) { /* multi line comment */ if (collection.GetElementBy(HostfileEntryType.Comment, line.MultiLineCommentText) == null) { collection.Add(new Comment(line.MultiLineCommentText, hostFile.PropertyChangedCallBack)); } } else if (line.IsToggleModeOption) { string value = line.Values.FirstOrDefault(); if (value != null) { /* group toggle-mode */ if (value.Equals("group", StringComparison.OrdinalIgnoreCase)) { hostFile.ExclusiveGroupToggleModeIsEnabled = true; } /* host toggle-mode */ if (value.Equals("host", StringComparison.OrdinalIgnoreCase)) { hostFile.ExclusiveHostToggleModeIsEnabled = true; } } } else if (line.IsGlobalComment) { /* single comment */ collection.Add(new Comment(line.Values.FirstOrDefault(), hostFile.PropertyChangedCallBack)); } else if (line.IsGroupStart) { /* host group */ HostGroup group = new HostGroup(line.GroupName, line.DescriptionText, hostFile.PropertyChangedCallBack); collection.Add(group); } else if (line.IsHost) { /* host */ IHostfileEntry parentItem = line.IsMemberOfHostGroup ? collection.GetElementBy( HostfileEntryType.HostGroup, line.GroupName) : null; HostGroup parentGroup = parentItem != null ? parentItem as HostGroup : null; Host host = new Host(parentGroup, line.Values.FirstOrDefault(), line.DescriptionText, hostFile.PropertyChangedCallBack) { IsActive = line.IsActive }; /* domains */ string domainString = line.Values.LastOrDefault(); if (string.IsNullOrEmpty(domainString) == false) { List<string> domainNames = domainString.Split(' ').Select(domain => domain.Trim()).ToList(); foreach (string domainName in domainNames) { host.Childs.Add(new Domain(host, domainName, hostFile.PropertyChangedCallBack)); } } if (parentGroup != null) { parentGroup.Childs.Add(host); } else { collection.Add(host); } } } /* attach entry collection to host file */ hostFile.Childs = collection; return hostFile; }