Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="commandLine"></param>
        /// <param name="serviceStopToken"></param>
        /// <exception cref="System.OperationCanceledException">Service stop has been requested.</exception>
        /// <exception cref="System.AggregateException"></exception>
        /// <exception cref="System.Exception"></exception>
        // This function is expected to synchronously start the service and wait for the cancellation token to be signaled,
        // indicating the service should stop. When that happens, it should throw OperationCanceledException
        private static void StartServiceAndWaitThrowOpCanceled(CommandLineArgs commandLine, Config config, CancellationToken serviceStopToken)
        {
            serviceStopToken.ThrowIfCancellationRequested();

            PgMalTrainingDataLoaderFactory trainingDataLoaderFactory = new PgMalTrainingDataLoaderFactory(config.ConnectionStrings.AnimeRecs);

            (MalTrainingData initialTrainingData, IDictionary <int, IList <int> > initialPrereqs) = LoadInitialData(trainingDataLoaderFactory, serviceStopToken);

            // TcpRecService constructor does not start the service and does not block on anything.
            using (TcpRecService recService = new TcpRecService(commandLine.PortNumber, trainingDataLoaderFactory, initialTrainingData, initialPrereqs))
            {
                // Load rec sources into the rec service before listening for connections.
                LoadRecSources(recService, config, serviceStopToken);

                // Start listening for connections. Does not block.
                recService.Start();
                Logging.Log.InfoFormat("Started listening on port {0}.", commandLine.PortNumber);

                // Wait for a service stop request to come in.
                serviceStopToken.WaitHandle.WaitOne();

                // Stop the service, letting connections drain for a few seconds after stopping listening for new connections.
                const int connectionDrainTimeoutInSeconds = 5;
                recService.Stop(TimeSpan.FromSeconds(connectionDrainTimeoutInSeconds));

                // Throw OperationCanceledException to notify caller that the service was stopped in an orderly manner.
                throw new OperationCanceledException(serviceStopToken);
            }
        }
Example #2
0
        // Loads all configured rec sources into the rec service in parallel.
        // Does not return until complete or serviceStopToken is signaled.
        private static void LoadRecSources(TcpRecService recService, Config config, CancellationToken serviceStopToken)
        {
            if (config.RecSources.Count == 0)
            {
                Logging.Log.Info("No rec sources configured.");
                return;
            }

            Logging.Log.InfoFormat("Loading {0} rec sources.", config.RecSources.Count);

            List <ICancellableTask> recSourceLoadTasks = new List <ICancellableTask>(config.RecSources.Count);

            using (CancellationTokenSource anyTaskFaultedOrCanceled = new CancellationTokenSource())
                using (CancellationTokenSource cancelTokenSource = CancellationTokenSource.CreateLinkedTokenSource(serviceStopToken, anyTaskFaultedOrCanceled.Token))
                {
                    foreach (DTO.LoadRecSourceRequest recSourceConfigX in config.RecSources)
                    {
                        DTO.LoadRecSourceRequest recSourceConfig = recSourceConfigX; // Don't capture the loop variable
                        Task loadRecSourceTask = Task.Factory.StartNew(() =>
                        {
                            recService.LoadRecSource(recSourceConfig, cancelTokenSource.Token);
                        }, cancelTokenSource.Token);
                        recSourceLoadTasks.Add(new CancellableTask(loadRecSourceTask, anyTaskFaultedOrCanceled));
                    }

                    try
                    {
                        AsyncUtils.WhenAllCancelOnFirstExceptionDontWaitForCancellations(recSourceLoadTasks).ConfigureAwait(false).GetAwaiter().GetResult();
                    }
                    catch (OperationCanceledException)
                    {
                        Logging.Log.Info("Canceled loading rec sources.");
                        throw;
                    }
                }

            recService.FinalizeRecSources(serviceStopToken);
        }
Example #3
0
        static void Main(string[] args)
        {
            System.Threading.Thread.CurrentThread.Name = "Main";
            Logging.SetUpLogging();

            try
            {
                CommandLineArgs commandLine = new CommandLineArgs(args);
                if (commandLine.ShowHelp)
                {
                    commandLine.DisplayHelp(Console.Out);
                    return;
                }

                ConfigRoot config = null;
                if (commandLine.ConfigFile != null)
                {
                    config = ConfigRoot.LoadFromFile(commandLine.ConfigFile);
                }

                string connectionString = ConfigurationManager.ConnectionStrings["Postgres"].ToString();
                PgMalTrainingDataLoaderFactory trainingDataLoaderFactory = new PgMalTrainingDataLoaderFactory(connectionString);
                using (TcpRecService recService = new TcpRecService(trainingDataLoaderFactory, commandLine.PortNumber))
                {
                    recService.Start();

                    if (config != null)
                    {
                        using (AnimeRecsClient client = new AnimeRecsClient(commandLine.PortNumber))
                        {
                            foreach (DTO.LoadRecSourceRequest recSourceToLoad in config.RecSources)
                            {
                                client.LoadRecSource(recSourceToLoad);
                            }

                            if (config.FinalizeAfterLoad)
                            {
                                client.FinalizeRecSources();
                            }
                        }
                    }

            #if MONO
                    Logging.Log.InfoFormat("Started listening on port {0}. Press ctrl+c to stop.", commandLine.PortNumber);
                    WaitForUnixStopSignal();
            #else

                    Logging.Log.InfoFormat("Started listening on port {0}. Press any key to stop.", commandLine.PortNumber);
                    Console.ReadKey();
            #endif

                    Logging.Log.InfoFormat("Got stop signal.");
                }
                Logging.Log.InfoFormat("Shutdown complete.");
            }
            catch (Exception ex)
            {
                Logging.Log.FatalFormat("Fatal error: {0}", ex, ex.Message);
                Environment.ExitCode = 1;
            }
        }