Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cancelRunner"></param>
        /// <param name="companyConfig"></param>
        /// <param name="runnerProgress"></param>
        /// <returns></returns>
        private ServiceTaskResult RunWindowsService(CancellationToken cancelRunner, CompanyConfig companyConfig,
                                                    ServiceProgressInfo runnerProgress)
        {
            // NOTE: In order to get the initial code delivered, I am reusing the code, or parts of it at least,
            //		 from the original MakoRunner project that uses the Topshelf library. This is not ideal since
            //		 we lose a great deal of control over our services. However, we know the code works for one
            //		 company ID at a time, which is why I'm reusing here, in the Sequential portion of the IF clause.

            //
            TopshelfExitCode retCode = HostFactory.Run(x =>
            {
                x.Service <TopshelfWindowsService>(sc =>
                {
                    sc.ConstructUsing(name => new TopshelfWindowsService(companyConfig, runnerProgress));
                    sc.WhenStarted((s, hostControl) => s.Start(hostControl));
                    sc.WhenShutdown(s => s.Shutdown());
                    sc.WhenStopped((s, hostControl) => s.Stop(hostControl));
                });
                //
                x.SetServiceName($"CommRunner {companyConfig.CompanyName + companyConfig.CompanyId}");
                x.SetDescription($"Mako Commission Runner for CompanyID ({companyConfig.CompanyId})");
                x.SetDisplayName($"Mako Commission Runner {companyConfig.CompanyId}");
                //
                //x.StartAutomaticallyDelayed();
            });
            //
            int exitCode = (int)Convert.ChangeType(retCode, retCode.GetTypeCode());

            // Create and return a ServiceTaskResult.
            // TODO: Add properties to the ServiceTaskResult and populate based on service exit code, etc.
            return(new ServiceTaskResult()
            {
                ServiceReturnCode = exitCode
            });
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="companyConfig"></param>
        /// <param name="serviceProgressInfo"></param>
        protected BaseTopshelfWindowsService(CompanyConfig companyConfig, ServiceProgressInfo serviceProgressInfo)
        {
            //
            MakoSocket = new ServicesWebSocket();

            // Create the log provider to log progress.
            if (MakoLogger == null)
            {
                MakoLogger = new DelegateLogProvider();
            }

            // Set the event handler for change events.
            MakoLogger._onProgressUpdate += MakoLogger__onProgressUpdate;

            //
            ServiceProgressInfo = serviceProgressInfo;

            //
            Config = companyConfig;
        }
Ejemplo n.º 3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="companyConfig"></param>
 /// <param name="serviceProgressInfo"></param>
 public TopshelfWindowsService(CompanyConfig companyConfig, ServiceProgressInfo serviceProgressInfo) :
     base(companyConfig, serviceProgressInfo)
 {
 }
Ejemplo n.º 4
0
        /// <inheritdoc />
        /// <summary>
        /// The Start method will create and start the task(s).
        /// </summary>
        public override void Start()
        {
            // Make sure that the RunnerInfo object is non-null.
            if (Info == null)
            {
                throw new ApplicationException($"RunnerInfo has not been allocated for Runner with ID: {MyRunnerId}");
            }

            // We will create and start Tasks based on the values in the RunnerInfo object.
            if ((Info.SequentialOrParallel == ProcessingOrder.Sequential ||
                 Info.SequentialOrParallel == ProcessingOrder.Undefined) &&
                !CanRunInParallel)
            {
                // All company IDs will be processed sequentially.
                foreach (var infoCompanyId in Info.CompanyIds)
                {
                    try
                    {
                        // Retrieve the encoded Company Configuration data from the Settings.
                        var encodedCompanyConfig = Settings.Default["CompanyId" + infoCompanyId].ToString();

                        // Convert the encoded company configuration value to a byte array.
                        var data = Convert.FromBase64String(encodedCompanyConfig);

                        // Decode the byte array to a string.
                        var decodedString = Encoding.UTF8.GetString(data);

                        // Deserialize the decoded string to a CompanyConfig object.
                        var config = JsonConvert.DeserializeObject <CompanyConfig>(decodedString);

                        // Create a ProgressInfo object.
                        var runnerProgress = new ServiceProgressInfo();

                        // Create a new CancellationTokenSource.
                        var tokenSource = new CancellationTokenSource();

                        // Create a Cancellation Token.
                        var cancelRunner = tokenSource.Token;

                        // Create and start a Task using the Windows service library currently being used.
                        Task <ServiceTaskResult> newTask = new Task <ServiceTaskResult>(() =>
                                                                                        RunWindowsService(cancelRunner, config, runnerProgress), cancelRunner, TaskCreationOptions.LongRunning);

                        // Store the Task in the RunerInfo for this Mako Runner.
                        if (Info.RunnerTaskWithResult != null)
                        {
                            // Add the Task to the List of this type of Task.
                            Info.RunnerTaskWithResult.Add(newTask);

                            // Save the Task and associated CancellationTokenSource.
                            Info.TaskTokenSources.Add(newTask, tokenSource);

                            // Start the Task.
                            newTask.Start();
                        }
                        else
                        {
                            throw new ApplicationException($"The RunnerInfo object's RunnerTaskWithResult property has not been initialized.");
                        }
                    }
                    catch (Exception e)
                    {
                        // TODO: Instead of throwing an exception and breaking the loop, log the error and continue.
                        throw new ApplicationException("Error starting Windows Service for company ID" + infoCompanyId, e);
                    }
                }
            }
            else if (Info.SequentialOrParallel == ProcessingOrder.Parallel && CanRunInParallel)
            {
                // All company IDs will be processed in parallel, up to a predefined maximum number of parallel tasks.
                // TODO: Define maximum number of parallel tasks and add to read that value.
            }
            else
            {
                throw new ApplicationException("Error in ServerMakoRunner.Start(). Invalid processing order.");
            }
        }