public async Task TestSessionClosed() { using var workspace = CreateWorkspace(); using var client = await InProcRemoteHostClient.GetTestClientAsync(workspace).ConfigureAwait(false); var serviceName = new RemoteServiceName("Test"); // register local service TestService testService = null; client.RegisterService(serviceName, (s, p, o) => { testService = new TestService(s, p); return(testService); }); // create session that stay alive until client alive (ex, SymbolSearchUpdateEngine) using var connection = await client.CreateConnectionAsync(serviceName, callbackTarget : null, CancellationToken.None); // mimic unfortunate call that happens to be in the middle of communication. var task = connection.RunRemoteAsync("TestMethodAsync", solution: null, arguments: null, CancellationToken.None); // make client to go away client.Dispose(); // let the service to return testService.Event.Set(); // make sure task finished gracefully await task; }
public async Task TestSessionClosed() { // enable local remote host service var service = CreateRemoteHostClientService(); service.Enable(); var client = (InProcRemoteHostClient)await service.TryGetRemoteHostClientAsync(CancellationToken.None); var serviceName = new RemoteServiceName("Test"); // register local service TestService testService = null; client.RegisterService(serviceName, (s, p) => { testService = new TestService(s, p); return(testService); }); // create session that stay alive until client alive (ex, SymbolSearchUpdateEngine) using var session = await client.TryCreateKeepAliveSessionAsync(serviceName, callbackTarget : null, CancellationToken.None); // mimic unfortunate call that happens to be in the middle of communication. var task = session.RunRemoteAsync("TestMethodAsync", solution: null, arguments: null, CancellationToken.None); // make client to go away service.Disable(); // let the service to return testService.Event.Set(); // make sure task finished gracefully await task; }
public static async Task <Stream> RequestServiceAsync( HostWorkspaceServices services, HubClient client, RemoteServiceName serviceName, HostGroup hostGroup, CancellationToken cancellationToken) { var is64bit = RemoteHostOptions.IsServiceHubProcess64Bit(services); var descriptor = new ServiceDescriptor(serviceName.ToString(is64bit)) { 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(services, e); // TODO: Propagate the original exception (see https://github.com/dotnet/roslyn/issues/40476) throw new SoftCrashException("Unexpected exception from HubClient", e, cancellationToken); }
private void Free(RemoteServiceName serviceName, Connection connection) { using (_shutdownLock.DisposableRead()) { if (_isDisposed) { // pool is not being used or // manager is already shutdown connection.Dispose(); return; } // queue must exist var queue = _pools[serviceName]; if (queue.Count >= _capacity) { // let the connection actually go away connection.Dispose(); return; } // pool the connection queue.Enqueue(connection); } }
public override async Task <RemoteServiceConnection> CreateConnectionAsync(RemoteServiceName serviceName, object?callbackTarget, CancellationToken cancellationToken) { // get stream from service hub to communicate service specific information // this is what consumer actually use to communicate information var serviceStream = await _inprocServices.RequestServiceAsync(serviceName).ConfigureAwait(false); return(new JsonRpcConnection(_workspaceServices, _logger, callbackTarget, serviceStream, poolReclamation: null)); }
protected override async Task <Connection?> TryCreateConnectionAsync( RemoteServiceName serviceName, object?callbackTarget, CancellationToken cancellationToken) { // get stream from service hub to communicate service specific information // this is what consumer actually use to communicate information var serviceStream = await _inprocServices.RequestServiceAsync(serviceName).ConfigureAwait(false); return(new JsonRpcConnection(Services, _inprocServices.Logger, callbackTarget, serviceStream)); }
public Task <Stream> RequestServiceAsync(RemoteServiceName serviceName) { if (_creatorMap.TryGetValue(serviceName, out var creator)) { var tuple = FullDuplexStream.CreateStreams(); return(Task.FromResult <Stream>(new WrappedStream(creator(tuple.Item1, _serviceProvider), tuple.Item2))); } throw ExceptionUtilities.UnexpectedValue(serviceName); }
public async Task <RemoteServiceConnection> GetOrCreateConnectionAsync(RemoteServiceName serviceName, CancellationToken cancellationToken) { var pool = _pools.GetOrAdd(serviceName, _ => new Pool(this)); if (pool.TryAcquire(out var connection)) { return(connection); } return(await _connectionFactory(serviceName, pool, cancellationToken).ConfigureAwait(false)); }
public async Task <Connection> GetOrCreateConnectionAsync(RemoteServiceName serviceName, CancellationToken cancellationToken) { var queue = _pools.GetOrAdd(serviceName, _ => new ConcurrentQueue <Connection>()); if (queue.TryDequeue(out var connection)) { return(new PooledConnection(this, serviceName, connection)); } var newConnection = await _connectionFactory(serviceName, cancellationToken).ConfigureAwait(false); return(new PooledConnection(this, serviceName, newConnection)); }
public void RegisterService(RemoteServiceName serviceName, Func <Stream, IServiceProvider, ServiceActivationOptions, ServiceBase> serviceCreator) => _inprocServices.RegisterService(serviceName, serviceCreator);
internal RazorLanguageServiceClient(RemoteHostClient client, string serviceName) { _client = client; _serviceName = new RemoteServiceName(serviceName); }
public Task <Stream> RequestServiceAsync(RemoteServiceName serviceName) => _inprocServices.RequestServiceAsync(serviceName);
public void RegisterService(RemoteServiceName name, Func <Stream, IServiceProvider, ServiceBase> serviceCreator) => _creatorMap.Add(name, serviceCreator);
public PooledConnection(ConnectionPool pool, RemoteServiceName serviceName, Connection connection) { _pool = pool; _serviceName = serviceName; _connection = connection; }