Ejemplo n.º 1
0
        private async Task EnsureVirtualConnectionClientCreated()
        {
            // Asynchronous equivalent to a 'lock(...) { ... }'
            await _connectionCreationSemaphore.WaitAsync();

            try
            {
                if (_virtualConnectionClient == null)
                {
                    _physicalConnection = StreamConnection.Create();

                    var connection = await _physicalConnection.Open(_socketAddress);

                    _virtualConnectionClient          = new VirtualConnectionClient(connection);
                    _virtualConnectionClient.OnError += (ex) =>
                    {
                        // This callback is fired only if there's a protocol-level failure (e.g., child process disconnected
                        // unexpectedly). It does *not* fire when RPC calls return errors. Since there's been a protocol-level
                        // failure, this Node instance is no longer usable and should be discarded.
                        _connectionHasFailed = true;

                        OutputLogger.LogError(0, ex, ex.Message);
                    };
                }
            }
            finally
            {
                _connectionCreationSemaphore.Release();
            }
        }
Ejemplo n.º 2
0
        private async Task <VirtualConnectionClient> GetOrCreateVirtualConnectionClientAsync()
        {
            var client = _currentVirtualConnectionClient;

            if (client == null)
            {
                await _clientModificationSemaphore.WaitAsync();

                try
                {
                    if (_currentVirtualConnectionClient == null)
                    {
                        var address = _addressForNextConnection;
                        if (string.IsNullOrEmpty(address))
                        {
                            // This shouldn't happen, because we always await 'EnsureReady' before getting here.
                            throw new InvalidOperationException("Cannot open connection to Node process until it has signalled that it is ready");
                        }

                        _currentPhysicalConnection = StreamConnection.Create();

                        var connection = await _currentPhysicalConnection.Open(address);

                        _currentVirtualConnectionClient          = new VirtualConnectionClient(connection);
                        _currentVirtualConnectionClient.OnError += (ex) =>
                        {
                            // TODO: Log the exception properly. Need to change the chain of calls up to this point to supply
                            // an ILogger or IServiceProvider etc.
                            Console.WriteLine(ex.Message);
                            ExitNodeProcess(); // We'll restart it next time there's a request to it
                        };
                    }

                    return(_currentVirtualConnectionClient);
                }
                finally
                {
                    _clientModificationSemaphore.Release();
                }
            }
            else
            {
                return(client);
            }
        }