private void TryAskForServerFailureActionViaClient(ServerFailureEventArgs args)
        {
            var requestId            = Guid.NewGuid();
            var response             = default(ServerFailureActionReplyEventArgs);
            var responseEvent        = new AutoResetEvent(false);
            var responseEventHandler = new CommunicationEventHandler <ServerFailureActionReplyEventArgs>((a) =>
            {
                if (a.RequestId == requestId)
                {
                    response = a;
                    responseEvent.Set();
                }
            });

            runtimeHost.ServerFailureActionReceived += responseEventHandler;

            var communication = sessionContext.ClientProxy.RequestServerFailureAction(args.Message, args.ShowFallback, requestId);

            if (communication.Success)
            {
                responseEvent.WaitOne();
                args.Abort    = response.Abort;
                args.Fallback = response.Fallback;
                args.Retry    = response.Retry;
            }
            else
            {
                args.Abort    = true;
                args.Fallback = false;
                args.Retry    = false;
            }

            runtimeHost.ServerFailureActionReceived -= responseEventHandler;
        }
        private void TryGetPasswordViaClient(PasswordRequiredEventArgs args)
        {
            var requestId            = Guid.NewGuid();
            var response             = default(PasswordReplyEventArgs);
            var responseEvent        = new AutoResetEvent(false);
            var responseEventHandler = new CommunicationEventHandler <PasswordReplyEventArgs>((a) =>
            {
                if (a.RequestId == requestId)
                {
                    response = a;
                    responseEvent.Set();
                }
            });

            runtimeHost.PasswordReceived += responseEventHandler;

            var communication = sessionContext.ClientProxy.RequestPassword(args.Purpose, requestId);

            if (communication.Success)
            {
                responseEvent.WaitOne();
                args.Password = response.Password;
                args.Success  = response.Success;
            }
            else
            {
                args.Password = default(string);
                args.Success  = false;
            }

            runtimeHost.PasswordReceived -= responseEventHandler;
        }
        private MessageBoxResult ShowMessageBoxViaClient(string message, string title, MessageBoxAction action, MessageBoxIcon icon)
        {
            var requestId            = Guid.NewGuid();
            var result               = MessageBoxResult.None;
            var response             = default(MessageBoxReplyEventArgs);
            var responseEvent        = new AutoResetEvent(false);
            var responseEventHandler = new CommunicationEventHandler <MessageBoxReplyEventArgs>((args) =>
            {
                if (args.RequestId == requestId)
                {
                    response = args;
                    responseEvent.Set();
                }
            });

            runtimeHost.MessageBoxReplyReceived += responseEventHandler;

            var communication = sessionContext.ClientProxy.ShowMessage(message, title, (int)action, (int)icon, requestId);

            if (communication.Success)
            {
                responseEvent.WaitOne();
                result = (MessageBoxResult)response.Result;
            }

            runtimeHost.MessageBoxReplyReceived -= responseEventHandler;

            return(result);
        }
        private void TryAskForExamSelectionViaClient(ExamSelectionEventArgs args)
        {
            var exams                = args.Exams.Select(e => (e.Id, e.LmsName, e.Name, e.Url));
            var requestId            = Guid.NewGuid();
            var response             = default(ExamSelectionReplyEventArgs);
            var responseEvent        = new AutoResetEvent(false);
            var responseEventHandler = new CommunicationEventHandler <ExamSelectionReplyEventArgs>((a) =>
            {
                if (a.RequestId == requestId)
                {
                    response = a;
                    responseEvent.Set();
                }
            });

            runtimeHost.ExamSelectionReceived += responseEventHandler;

            var communication = sessionContext.ClientProxy.RequestExamSelection(exams, requestId);

            if (communication.Success)
            {
                responseEvent.WaitOne();
                args.SelectedExam = args.Exams.First(e => e.Id == response.SelectedExamId);
                args.Success      = response.Success;
            }
            else
            {
                args.SelectedExam = default(Exam);
                args.Success      = false;
            }

            runtimeHost.ExamSelectionReceived -= responseEventHandler;
        }
        public OperationResult Revert()
        {
            StatusChanged?.Invoke(TextKey.OperationStatus_WaitRuntimeDisconnection);

            if (clientHost.IsConnected)
            {
                var disconnected             = false;
                var disconnectedEvent        = new AutoResetEvent(false);
                var disconnectedEventHandler = new CommunicationEventHandler(() => disconnectedEvent.Set());

                clientHost.RuntimeDisconnected += disconnectedEventHandler;

                logger.Info("Waiting for runtime to disconnect from client communication host...");
                disconnected = disconnectedEvent.WaitOne(timeout_ms);

                clientHost.RuntimeDisconnected -= disconnectedEventHandler;

                if (disconnected)
                {
                    logger.Info("The runtime has successfully disconnected from the client communication host.");
                }
                else
                {
                    logger.Error($"The runtime failed to disconnect within {timeout_ms / 1000} seconds!");

                    return(OperationResult.Failed);
                }
            }
            else
            {
                logger.Info("The runtime has already disconnected from the client communication host.");
            }

            return(OperationResult.Success);
        }
Esempio n. 6
0
        private bool TryTerminateConnection()
        {
            var serviceEvent        = new AutoResetEvent(false);
            var serviceEventHandler = new CommunicationEventHandler(() => serviceEvent.Set());

            runtimeHost.ServiceDisconnected += serviceEventHandler;

            var success = service.Disconnect();

            if (success)
            {
                logger.Info("Successfully disconnected from service. Waiting for service to disconnect...");

                success = serviceEvent.WaitOne(timeout_ms);

                if (success)
                {
                    logger.Info("Service disconnected successfully.");
                }
                else
                {
                    logger.Error($"Service failed to disconnect within {timeout_ms / 1000} seconds!");
                }
            }
            else
            {
                logger.Error("Failed to disconnect from service!");
            }

            runtimeHost.ServiceDisconnected -= serviceEventHandler;

            return(success);
        }
        private bool TryStartClient()
        {
            var authenticationToken = Context.Next.ClientAuthenticationToken.ToString("D");
            var executablePath      = Context.Next.AppConfig.ClientExecutablePath;
            var logFilePath         = $"{'"' + Context.Next.AppConfig.ClientLogFilePath + '"'}";
            var logLevel            = Context.Next.Settings.LogLevel.ToString();
            var runtimeHostUri      = Context.Next.AppConfig.RuntimeAddress;
            var uiMode = Context.Next.Settings.UserInterfaceMode.ToString();

            var clientReady             = false;
            var clientReadyEvent        = new AutoResetEvent(false);
            var clientReadyEventHandler = new CommunicationEventHandler(() => clientReadyEvent.Set());

            var clientTerminated             = false;
            var clientTerminatedEventHandler = new ProcessTerminatedEventHandler(_ => { clientTerminated = true; clientReadyEvent.Set(); });

            logger.Info("Starting new client process...");
            runtimeHost.AllowConnection     = true;
            runtimeHost.AuthenticationToken = Context.Next.ClientAuthenticationToken;
            runtimeHost.ClientReady        += clientReadyEventHandler;
            ClientProcess             = processFactory.StartNew(executablePath, logFilePath, logLevel, runtimeHostUri, authenticationToken, uiMode);
            ClientProcess.Terminated += clientTerminatedEventHandler;

            logger.Info("Waiting for client to complete initialization...");
            clientReady = clientReadyEvent.WaitOne();

            runtimeHost.AllowConnection     = false;
            runtimeHost.AuthenticationToken = default(Guid?);
            runtimeHost.ClientReady        -= clientReadyEventHandler;
            ClientProcess.Terminated       -= clientTerminatedEventHandler;

            if (clientReady && !clientTerminated)
            {
                return(TryStartCommunication());
            }

            if (!clientReady)
            {
                logger.Error($"Failed to start client!");
            }

            if (clientTerminated)
            {
                logger.Error("Client instance terminated unexpectedly during initialization!");
            }

            return(false);
        }
Esempio n. 8
0
        private bool TryStopSession()
        {
            var failure             = false;
            var success             = false;
            var serviceEvent        = new AutoResetEvent(false);
            var failureEventHandler = new CommunicationEventHandler(() => { failure = true; serviceEvent.Set(); });
            var successEventHandler = new CommunicationEventHandler(() => { success = true; serviceEvent.Set(); });

            runtimeHost.ServiceFailed         += failureEventHandler;
            runtimeHost.ServiceSessionStopped += successEventHandler;

            logger.Info("Stopping current service session...");

            var communication = service.StopSession(Context.Current.Id);

            if (communication.Success)
            {
                serviceEvent.WaitOne(timeout_ms);

                if (success)
                {
                    logger.Info("Successfully stopped service session.");
                }
                else if (failure)
                {
                    logger.Error("An error occurred while attempting to stop the current service session! Please check the service log for further information.");
                }
                else
                {
                    logger.Error($"Failed to stop service session within {timeout_ms / 1000} seconds!");
                }
            }
            else
            {
                logger.Error("Failed to communicate session stop to service!");
            }

            runtimeHost.ServiceFailed         -= failureEventHandler;
            runtimeHost.ServiceSessionStopped -= successEventHandler;

            return(success);
        }
        private bool TryStopClient()
        {
            var success = false;

            var disconnected             = false;
            var disconnectedEvent        = new AutoResetEvent(false);
            var disconnectedEventHandler = new CommunicationEventHandler(() => disconnectedEvent.Set());

            var terminated             = false;
            var terminatedEvent        = new AutoResetEvent(false);
            var terminatedEventHandler = new ProcessTerminatedEventHandler((_) => terminatedEvent.Set());

            if (ClientProxy != null)
            {
                runtimeHost.ClientDisconnected += disconnectedEventHandler;
                ClientProcess.Terminated       += terminatedEventHandler;

                logger.Info("Instructing client to initiate shutdown procedure.");
                ClientProxy.InitiateShutdown();

                logger.Info("Disconnecting from client communication host.");
                ClientProxy.Disconnect();

                logger.Info("Waiting for client to disconnect from runtime communication host...");
                disconnected = disconnectedEvent.WaitOne(timeout_ms / 2);

                if (!disconnected)
                {
                    logger.Error($"Client failed to disconnect within {timeout_ms / 2 / 1000} seconds!");
                }

                logger.Info("Waiting for client process to terminate...");
                terminated = terminatedEvent.WaitOne(timeout_ms / 2);

                if (!terminated)
                {
                    logger.Error($"Client failed to terminate within {timeout_ms / 2 / 1000} seconds!");
                }

                runtimeHost.ClientDisconnected -= disconnectedEventHandler;
                ClientProcess.Terminated       -= terminatedEventHandler;
            }

            if (disconnected && terminated)
            {
                logger.Info("Client has been successfully terminated.");
                success = true;
            }
            else
            {
                logger.Warn("Attempting to kill client process since graceful termination failed!");
                success = TryKillClient();
            }

            if (success)
            {
                ClientProcess = null;
                ClientProxy   = null;
            }

            return(success);
        }
 /// <summary>
 /// Executes the event handler asynchronously, i.e. on a separate thread.
 /// </summary>
 public static async Task InvokeAsync <T>(this CommunicationEventHandler <T> handler, T args) where T : CommunicationEventArgs
 {
     await Task.Run(() => handler?.Invoke(args));
 }
 /// <summary>
 /// Executes the event handler asynchronously, i.e. on a separate thread.
 /// </summary>
 public static async Task InvokeAsync(this CommunicationEventHandler handler)
 {
     await Task.Run(() => handler?.Invoke());
 }