コード例 #1
0
        private void Runner()
        {
            ThreadStart ModuleEntryPoint     = null;
            bool        finishedSuccessfully = true;
            int         moduleFailureCount   = 0;
            DateTime    failureResetTimer    = DateTime.UtcNow;

            do
            {
                // create and initialize module
                while (ModuleEntryPoint == null)
                {
                    try
                    {
                        CancellationTokenSource?.Dispose();
                        CancellationTokenSource = new CancellationTokenSource();
                        CancellationToken       = CancellationTokenSource.Token;
                        InputModule             = Server.CreateModule <IInputModule>(ModuleDefinition);
                        InputModule.LoadConfiguration(ModuleConfiguration);
                        InputModule.SetMessageSender(MessageAcceptor);
                        InputModule.Initialize();
                        ModuleEntryPoint  = InputModule.GetWorker(CancellationToken);
                        failureResetTimer = DateTime.UtcNow;
                    }
                    catch (Exception e)
                    {
                        Server.Logger?.LogEvent(this, Severity.Error, "InputModule", $"Failed to re/create '{ModuleKey}'. Next retry in {ModuleReloadTimeoutSeconds} seconds.", e);
                        ModuleEntryPoint = null;
                        // pause before next attempt
                        for (int waitCount = 0; waitCount < 100; waitCount++)
                        {
                            if (CancellationToken.IsCancellationRequested)
                            {
                                break;
                            }
                            Thread.Sleep(ModuleReloadTimeoutSeconds * 10); // effectively * 1000, i.e. seconds => milliseconds
                        }
                        if (CancellationToken.IsCancellationRequested && IsConfigurationReloadRequested)
                        {
                            continue;
                        }
                        // if canceled not for reload, and still unable to create, just mark completed and exit
                        if (CancellationToken.IsCancellationRequested)
                        {
                            WorkCompleted.Set();
                            return;
                        }
                    }
                }
                // working
                try
                {
                    ModuleEntryPoint.Invoke(); // ModuleEntryPoint != null, see above
                    if (IsConfigurationReloadRequested)
                    {
                        IsConfigurationReloadRequested = false;
                        try { InputModule.Destroy(); } catch { } // to avoid Invoke() catcher
                        ModuleEntryPoint = null; // to initiate module load
                    }
                    finishedSuccessfully = true;
                    if (CancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception e)
                {
                    if (DateTime.UtcNow.Subtract(failureResetTimer).TotalSeconds > 10 * ModuleReloadTimeoutSeconds)
                    {
                        failureResetTimer  = DateTime.UtcNow;
                        moduleFailureCount = 0;
                    }
                    Server.Logger.LogEvent(InputModule, Severity.Error, "InputModule", $"Unexpected input module failure. That's happened {moduleFailureCount + 1} times in the row.", e);
                    finishedSuccessfully = false;
                    Server.Logger.LogEvent(this, Severity.Error, "InputModule", $"Recreating input module. Next retry in {ModuleReloadTimeoutSeconds * moduleFailureCount} seconds.");
                    if (moduleFailureCount > 0)
                    {
                        Thread.Sleep(ModuleReloadTimeoutSeconds * moduleFailureCount * 1000); // pause before next attempt
                    }
                    // re-initialize the module
                    try { InputModule.Destroy(); } catch { }
                    ModuleEntryPoint = null;
                    moduleFailureCount++;
                }
            } while (!finishedSuccessfully && !CancellationToken.IsCancellationRequested);

            // All done, but let's drain the queue
            while (AttachedQueue.Count > 0)
            {
                Thread.Sleep(5);
            }
            WorkCompleted.Set();
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: MaxxVolk/YASLS.NET
        public YASLServer(ServerConfiguration serverConfiguration)
        {
            TokenSource = new CancellationTokenSource();

            // create inputs
            foreach (KeyValuePair <string, QueueDefinition> queueCfg in serverConfiguration.Queues)
            {
                MasterQueue newQueue = new MasterQueue(TokenSource.Token);
                masterQueues.Add(queueCfg.Key, new Tuple <MasterQueue, Thread>(newQueue, new Thread(newQueue.GetWorker())));
            }

            // create queues
            foreach (KeyValuePair <string, InputDefinition> inputCfg in serverConfiguration.Inputs)
            {
                InputDefinition inputDef        = inputCfg.Value;
                Type            inputModuleType = GetModuleAssembly(inputDef).GetType(inputDef.ManagedTypeName);
                IInputModule    newModule       = (IInputModule)Activator.CreateInstance(inputModuleType);
                newModule.Initialize(inputDef.ConfigurationJSON, TokenSource.Token, masterQueues.Where(z => serverConfiguration.Queues.Where(x => x.Value.Inputs.Contains(inputCfg.Key)).Select(y => y.Key).Contains(z.Key)).Select(t => t.Value.Item1));
                inputModules.Add(inputCfg.Key, new Tuple <IInputModule, Thread>(newModule, new Thread(newModule.GetWorker())));
            }
        }