private async Task InvokeEndpointManagerAsync()

in src/library/EndpointManagement/EndpointManagementClient.cs [241:322]


        private async Task<ResponseType> InvokeEndpointManagerAsync<RequestType, ResponseType>(RequestType request, CancellationToken cancellationToken, bool ensureEndpointManagerRunning = true)
            where RequestType : EndpointManagerRequest
            where ResponseType : EndpointManagerResult
        {
            if (ensureEndpointManagerRunning)
            {
                // We do not want invoke this method if we are calling from the 'Ping' method, as that will result in an infinite loop
                await EnsureEndpointManagerRunningAsync(cancellationToken);
            }

            var errorMessage = $"Could not connect to {EndpointManager.ProcessName}";
            ResponseType deserializedResult = null;

            try
            {
                using (var socket = _socketFactory.Invoke())
                using (cancellationToken.Register(() => socket.Close()))
                {
                    _log.Info($"Connecting to {EndpointManager.ProcessName}");

                    await socket.ConnectAsync(new UnixDomainSocketEndPoint(_socketFilePath));

                    // Wait for the EndpointManager handshake.
                    var result = await socket.ReadUntilEndMarkerAsync();
                    if (!result.Equals(EndpointManager.SocketHandshake))
                    {
                        throw new UnexpectedStateException($"Received unexpected message over socket: '{result}'", _log);
                    }

                    // Send api invocation request
                    var serializedRequest = JsonHelpers.SerializeObject(request);
                    _log.Info($"Sending request: '{serializedRequest}'");
                    await socket.SendWithEndMarkerAsync(serializedRequest);

                    // Wait for response
                    result = await socket.ReadUntilEndMarkerAsync();
                    _log.Info($"Received response: '{result}'");
                    deserializedResult = JsonHelpers.DeserializeObject<ResponseType>(result);
                }
            }
            catch (Exception ex) when (ex is SocketException socketException && (socketException.SocketErrorCode == SocketError.ConnectionRefused
                                                                                || socketException.SocketErrorCode == SocketError.AddressNotAvailable
                                                                                || socketException.SocketErrorCode == SocketError.NetworkDown))
            {
                // We expect to hit this case if the endpoint manager is not yet running.
                _log.Info($"{EndpointManager.ProcessName} is not running: '{ex.Message}' and socket error code: '{socketException.SocketErrorCode}'");
            }
            catch (Exception ex) when (ex is IUserVisibleExceptionReporter)
            {
                throw;
            }
            catch (Exception ex) when (ex.InnerException is DependencyResolutionException autofacEx
                && autofacEx.InnerException is SocketException socketEx
                && socketEx.SocketErrorCode == SocketError.AddressFamilyNotSupported)
            {
                throw new UserVisibleException(_operationContext, Resources.UnixDomainSocketsNotSupported, Product.Name);
            }
            catch (UnexpectedStateException)
            {
                throw;
            }
            catch (Exception ex)
            {
                _log.Exception(ex);
                throw new InvalidOperationException(errorMessage, ex);
            }

            if (deserializedResult != null && !deserializedResult.IsSuccess)
            {
                // Operation failed, but we got back a well-formed response. We check for user-visible error types
                if (Enum.TryParse(deserializedResult.ErrorType, out EndpointManager.Errors errorType) && errorType == EndpointManager.Errors.UserVisible)

                {
                    throw new UserVisibleException(_log.OperationContext, deserializedResult.ErrorMessage);
                }
                else
                {
                    throw new InvalidOperationException(deserializedResult.ErrorMessage);
                }
            }
            return deserializedResult;
        }