Beispiel #1
0
        public void Dispose()
        {
            runtimeLog?.Info("DirectorLoopShutdown");
            lock (lockRunning) {
                if (shuttingDown)
                {
                    return;
                }
                shuttingDown = true;
                __running__  = false;
            }
            List <ActorDisposeHandle> handles = null;

            lock (lockDisposeHandles) {
                handles        = disposeHandles;
                disposeHandles = null;
            }

            foreach (var handle in handles)
            {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                handle.DisposeProcess(getCurrentDispatchData);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }

            var singletonPocoInstantiators = new List <ActinInstantiator>();
            lock (this.lockInstantiators) {
                foreach (var instantiator in instantiators.Values)
                {
                    if (instantiator.IsRootSingleton && !instantiator.IsActor)
                    {
                        if (instantiator.HasSingletonInstance)
                        {
                            singletonPocoInstantiators.Add(instantiator);
                        }
                    }
                }
            }

            foreach (var instantiator in singletonPocoInstantiators)
            {
                var instance = instantiator.GetSingletonInstance(this);
                if (instantiator == null)
                {
                    continue;
                }
                try {
                    instantiator.DisposeChildren(instance);
                }
                catch (Exception ex) {
                    this.runtimeLog?.Error("Shutdown", $"{instantiator.Type.Name}.DisposeChildren", ex);
                }
                try {
                    var asDisposable = instance as IDisposable;
                    asDisposable?.Dispose();
                }
                catch (Exception ex) {
                    this.runtimeLog?.Error("Shutdown", $"{instantiator.Type.Name}.DisposeInstance", ex);
                }
            }

            lockDirectors.EnterWriteLock();
            try {
                var match = directors.FirstOrDefault(x => x.Value == this);
                if (match.Key != null)
                {
                    directors.Remove(match.Key);
                }
            }
            finally {
                lockDirectors.ExitWriteLock();
            }
        }
Beispiel #2
0
        //Main Loop ======================= Main Loop:
        async Task runMainLoop(ConfigureUtil config)
        {
            var poolCopy = new List <Actor_SansType>();

            void safeLog(string location, Exception ex)
            {
                try {
                    runtimeLog.Error(location, "Main Loop", ex);
                }
                catch { }
            }

            runtimeLog.Info("DirectorLoopStarted");
            bool readkeyFailed = false;

            while (Running)
            {
                try {
                    try {
                        if (!readkeyFailed && Environment.UserInteractive)
                        {
                            if (Console.KeyAvailable)
                            {
                                var key = Console.ReadKey(true).Key;
                                if (key == ConsoleKey.Q || key == ConsoleKey.Escape)
                                {
                                    this.Dispose();
                                    await Task.Delay(5000); //Simulate the time we normally get for shutdown.
                                }
                            }
                        }
                    }
                    catch (Exception ex) {
                        readkeyFailed = true;
                        safeLog("User Interactive Check", ex);
                    }

                    try {
                        poolCopy.Clear();
                        lock (lockProcessPool) {
                            poolCopy.AddRange(processPool);
                        }
                    }
                    catch (Exception ex) {
                        safeLog("Process Pool Copy", ex);
                    }

                    try {
                        var shouldRemove = poolCopy.Where(x => x.ShouldBeRemovedFromPool).ToList();
                        if (shouldRemove.Count > 0)
                        {
                            lock (lockProcessPool) {
                                processPool.RemoveAll(x => shouldRemove.Contains(x));
                                poolCopy.Clear();
                                poolCopy.AddRange(processPool);
                            }
                        }
                    }
                    catch (Exception ex) {
                        safeLog("Process Pool Pruning", ex);
                    }

                    List <ActorDisposeHandle> handles = null;
                    lock (lockDisposeHandles) {
                        handles = disposeHandles;
                    }

                    try {
                        var remainingHandles = new List <ActorDisposeHandle>();
                        if (handles != null)
                        {
                            foreach (var handle in handles)
                            {
                                if (handle.MustDispose)
                                {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                    handle.DisposeProcess(getCurrentDispatchData);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                }
                                else
                                {
                                    remainingHandles.Add(handle);
                                }
                            }
                            lock (lockDisposeHandles) {
                                if (disposeHandles != null)
                                {
                                    disposeHandles = remainingHandles;
                                }
                            }
                        }
                    }
                    catch (Exception ex) {
                        safeLog("Dispose Processes", ex);
                    }

                    try {
                        List <object> newDependencies = null;
                        lock (lockNewlyRegisteredDependencies) {
                            if (newlyRegisteredDependencies.Count > 0)
                            {
                                newDependencies = newlyRegisteredDependencies.ToList();
                                newlyRegisteredDependencies.Clear();
                            }
                        }
                        if (newDependencies != null)
                        {
                            foreach (var newDependency in newDependencies)
                            {
                                try {
                                    if (newDependency is Actor_SansType)
                                    {
                                        var process = newDependency as Actor_SansType;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                        process.Init(getCurrentDispatchData).ContinueWith(async task => {
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                            if (task.Status == TaskStatus.RanToCompletion)
                                            {
                                                if (task.Result != null)
                                                {
                                                    var handle         = task.Result;
                                                    var mustDisposeNow = false;
                                                    lock (lockDisposeHandles) {
                                                        if (disposeHandles != null)
                                                        {
                                                            lock (lockProcessPool) {
                                                                processPool.Add(process);
                                                            }
                                                            disposeHandles.Add(handle);
                                                        }
                                                        else
                                                        {
                                                            //Means that the whole application has been disposed.
                                                            mustDisposeNow = true;
                                                        }
                                                    }
                                                    if (mustDisposeNow)
                                                    {
                                                        await handle.DisposeProcess(getCurrentDispatchData);
                                                    }
                                                }
                                            }
                                        });
                                    }
                                    else if (newDependency is IOnInit)
                                    {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                        (newDependency as IOnInit).OnInit(new ActorUtil(newDependency as Actor_SansType, this.Clock));
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                    }
                                }
                                catch (Exception ex) {
                                    safeLog("Initializing Dependency", ex);
                                }
                            }
                        }
                    }
                    catch (Exception ex) {
                        safeLog("Initializing Dependencies", ex);
                    }

                    try {
                        foreach (var process in poolCopy)
                        {
                            try {
                                if (process.ShouldBeRunNow(process.IgnoreSimulatedTime? DateTimeOffset.Now : Clock.Now))
                                {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                    process.Run(getCurrentDispatchData);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                                }
                            }
                            catch (Exception ex) {
                                safeLog("Running Process", ex);
                            }
                        }
                    }
                    catch (Exception ex) {
                        safeLog("Running All Processes", ex);
                    }

                    await Task.Delay(new TimeSpan(0, 0, 0, 0, config.RunLoopIntervalMs));
                }
                catch (Exception ex) {
                    safeLog("main while", ex);
                }
            }
        }