Esempio n. 1
0
        private async Task ShutdownModule(ModuleState module)
        {
            State s = module.State;

            if (s == State.ShutdownStarted || s == State.ShutdownCompleted)
            {
                return;
            }

            module.State = State.ShutdownStarted;
            logger.Info($"Starting shutdown of module {module.Name}...");
            try {
                if (module.RunTask != null)
                {
                    await module.RunTask;
                }
                if (s == State.InitComplete || s == State.InitError)
                {
                    await module.Instance.InitAbort();
                }
                await module.FlushVariables();

                logger.Info($"Shutdown of module {module.Name} completed.");
            }
            catch (Exception exp) {
                string msg = $"Shutdown exception in module '{module.Name}': " + exp.Message;
                Log_Exception(Severity.Warning, exp, "ModuleShutdownError", msg, module.ID);
            }
            module.State = State.ShutdownCompleted;
            module.SetInstanceNull();
        }
Esempio n. 2
0
        private void StartRunningModule(ModuleState module)
        {
            module.State = State.Running;
            Func <bool> fShutdown = () => { return(module.State == State.ShutdownStarted); };
            Task        runTask   = module.Instance
                                    .Run(fShutdown)
                                    .ContinueOnMainThread((task) => {
                if (module.State == State.Running)
                {
                    string restartReason = "";
                    if (task.IsFaulted)
                    {
                        string msg = $"Module '{module.Name}' threw exception in Run: " + task.Exception !.GetBaseException().Message;
                        Log_Exception(Severity.Warning, task.Exception, "ModuleRunError", msg, module.ID);
                        restartReason = "Exception in Run";
                    }
                    else
                    {
                        restartReason = "Early return from Run";
                    }
                    Task.Delay(1000).ContinueOnMainThread((tt) => {
                        Task ignored = RestartModule(module, restartReason);
                    });
                }
            });

            module.RunTask = runTask;
        }
Esempio n. 3
0
        internal void Notify_AlarmOrEvent(ModuleState module, AlarmOrEventInfo e)
        {
            var ae = new AlarmOrEvent()
            {
                ModuleID        = module.ID,
                ModuleName      = module.Name,
                Time            = e.Time,
                IsSystem        = false,
                Severity        = e.Severity,
                Type            = e.Type,
                Message         = e.Message,
                Details         = e.Details,
                AffectedObjects = e.AffectedObjects,
                Initiator       = e.Initiator
            };

            reqHandler.OnAlarmOrEvent(ae);

            string msg = e.Message;

            switch (e.Severity)
            {
            case Severity.Info:
                module.logger.Info(msg);
                break;

            case Severity.Warning:
                module.logger.Warn(msg);
                break;

            case Severity.Alarm:
                module.logger.Error(msg);
                break;
            }
        }
Esempio n. 4
0
        internal async Task RestartModule(ModuleState module, string reason, int tryCounter = 0)
        {
            Log_Warn("ModuleRestart", $"Restarting module '{module.Name}'. Reason: {reason}", module.ID);

            const int TimeoutSeconds = 10;

            try {
                Task tShutdown = ShutdownModule(module);
                Task t         = await Task.WhenAny(tShutdown, Task.Delay(TimeSpan.FromSeconds(TimeoutSeconds)));

                if (t != tShutdown)
                {
                    string msg = $"Shutdown request for module '{module.Name}' failed to complete within {TimeoutSeconds} seconds.";
                    Log_Warn("ShutdownTimeout", msg, module.ID);
                    // go ahead and hope for the best...
                }
                if (shutdown)
                {
                    return;
                }
                module.CreateInstance();
                await InitModule(module);

                StartRunningModule(module);
            }
            catch (Exception exp) {
                Log_Exception(Severity.Alarm, exp, "ModuleRestartError", $"Restart of module '{module.Name}' failed: {exp.Message}", module.ID);
                int delayMS = Math.Min(10 * 1000, (tryCounter + 1) * 1000);
                await Task.Delay(delayMS);

                Task ignored = RestartModule(module, reason, tryCounter + 1);
            }
        }
Esempio n. 5
0
 internal void Notify_VariableValuesChanged(ModuleState module, List <VariableValue> values)
 {
     if (logger.IsDebugEnabled)
     {
         logger.Debug("VariableValuesChanged:\n\t" + string.Join("\n\t", values.Select(x => x.ToString())));
     }
     module.UpdateVariableValues(values);
 }
Esempio n. 6
0
        private Variable?GetVariableDescription(VariableRef varRef)
        {
            string      moduleID = varRef.Object.ModuleID;
            ModuleState module   = modules.FirstOrDefault(m => m.ID == moduleID);

            if (module == null)
            {
                return(null);
            }
            return(module.GetVarDescription(varRef));
        }
Esempio n. 7
0
        private async Task InitModule(ModuleState module)
        {
            Module info = module.Config;

            try {
                logger.Info($"Starting module {module.Name}...");
                VariableValue[] restoreVariableValues = module.GetVariableValues();

                var configItems = info.Config.ToList();

                if (!string.IsNullOrEmpty(info.ExternalCommand))
                {
                    configItems.Add(new NamedValue("ExternalCommand", info.ExternalCommand));
                }
                if (!string.IsNullOrEmpty(info.ExternalArgs))
                {
                    configItems.Add(new NamedValue("ExternalArgs", info.ExternalArgs));
                }

                var initInfo = new ModuleInitInfo()
                {
                    ModuleID      = module.ID,
                    ModuleName    = module.Name,
                    LoginPassword = module.Password,
                    LoginServer   = "localhost",
                    LoginPort     = listenPort,
                    DataFolder    = GetDataFolder(module.Config),
                    Configuration = configItems.ToArray(),
                    InProcApi     = reqHandler,
                };
                await module.Instance.Init(initInfo, restoreVariableValues, module, null);

                ObjectInfo[] allObjs = await module.Instance.GetAllObjects();

                module.SetAllObjects(allObjs);
                module.State = State.InitComplete;
                logger.Info($"Init of module {module.Name} completed.");
            }
            catch (Exception exp) {
                module.State     = State.InitError;
                module.LastError = exp.Message;
                throw new Exception($"Startup of module {info.Name} failed: " + exp.Message, exp);
            }
        }
Esempio n. 8
0
        internal void Notify_ConfigChanged(ModuleState module, List <ObjectRef> changedObjects)
        {
            try {
                Task <ObjectInfo[]> task = module.Instance.GetAllObjects();
                task.ContinueOnMainThread(t => {
                    if (t.IsFaulted)
                    {
                        var ignored = RestartModule(module, "GetAllObjects() failed in Notify_ConfigChanged: " + t.Exception?.Message);
                    }
                    else
                    {
                        ObjectInfo[] allObjs = t.Result;
                        module.SetAllObjects(allObjs);
                    }
                });
            }
            catch (Exception exp) {
                var ignored = RestartModule(module, "GetAllObjects() failed in Notify_ConfigChanged: " + exp.Message);
            }

            reqHandler.OnConfigChanged(changedObjects, module.GetObjectParent);
        }
Esempio n. 9
0
        internal void Notify_AlarmOrEvent(ModuleState module, AlarmOrEventInfo e)
        {
            Origin?initiator = e.Initiator;

            if (initiator.HasValue)
            {
                Origin origin = initiator.Value;
                string id     = origin.ID;
                if (origin.Type == OriginType.User)
                {
                    User user = userManagement.Users.FirstOrDefault(u => u.ID == id);
                    if (user != null)
                    {
                        origin.Name = user.Name;
                    }
                    else if (origin.Name == null)
                    {
                        origin.Name = "";
                    }
                }
                else if (origin.Type == OriginType.Module)
                {
                    var theModule = modules.FirstOrDefault(m => m.ID == id);
                    if (theModule != null)
                    {
                        origin.Name = theModule.Name;
                    }
                    else if (origin.Name == null)
                    {
                        origin.Name = "";
                    }
                }
                initiator = origin;
            }

            var ae = new AlarmOrEvent()
            {
                ModuleID        = module.ID,
                ModuleName      = module.Name,
                Time            = e.Time,
                IsSystem        = false,
                Severity        = e.Severity,
                ReturnToNormal  = e.ReturnToNormal,
                Type            = e.Type,
                Message         = e.Message,
                Details         = e.Details,
                AffectedObjects = e.AffectedObjects,
                Initiator       = initiator
            };

            reqHandler.OnAlarmOrEvent(ae);

            bool logInfo = module.UpdateWarningAlarmState(e);

            string msg = e.Message;

            switch (e.Severity)
            {
            case Severity.Info:
                if (logInfo)
                {
                    module.logger.Info(msg);
                }
                break;

            case Severity.Warning:
                module.logger.Warn(msg);
                break;

            case Severity.Alarm:
                module.logger.Error(msg);
                break;
            }
        }