Example #1
0
 public ConnectWindowGenTwo()
 {
     ConnectWindowGenTwo.log.Trace("ConnectWindowGenTwo");
     this.InitializeComponent();
     this.connectModel = new ControlConnectModel(this);
     this.connectModel.addControlConnectCallback(this);
     this.socketModel = new SocketModel(this);
     this.addSocketCallback();
     this.initView();
     ConnectWindowGenTwo.log.Trace("ip == " + ConfigureUtil.AdapterIP());
     ConnectWindowGenTwo.log.Trace("type = " + ConfigureUtil.getClientType());
     NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(ConnectWindowGenTwo.AddressChangedCallback);
     Console.WriteLine("Listening for address changes. Press any key to exit.");
 }
Example #2
0
        //Init ======================= Init:
        private async Task <ConfigureUtil> init(Action <ConfigureUtil> configure)
        {
            this.runtimeLog = new LogDispatcher(this.Clock);
            lock (lockRunning) {
                if (__running__)
                {
                    return(null);
                }
                __running__ = true;
            }
            this.AddSingletonDependency(this, typeof(ICreateInstanceActorForScene));

            //Get configuration from the user:
            var config = new ConfigureUtil();

            configure(config);
            config.Sanitize();

            //Add this director to the static list of running directors:
            lockDirectors.EnterWriteLock();
            try {
                if (directors.ContainsKey(config.DirectorName))
                {
                    throw new ApplicationException($"There is already a running director with the name '{config.DirectorName}'");
                }
                directors[config.DirectorName] = this;
            }
            finally {
                lockDirectors.ExitWriteLock();
            }

            //Get an instance of the start up log, or throw an exception:
            var   log = new LogDispatcherForActor(new LogDispatcher(this.Clock), "Before Start");
            Actor startUpLogAsActor;

            {
                var startUpLogInstantiator = new ActinInstantiator(config.StartUpLogType);
                if (!startUpLogInstantiator.Build((t) => {
                    throw new ApplicationException($"{config.StartUpLogType.Name} is being used as the 'StartUp' Log, and must not have any dependencies.");
                }))
                {
                    throw new ApplicationException($"{config.StartUpLogType.Name} is being used as the 'StartUp' Log, and must not have any dependencies.");
                }
                lock (lockInstantiators) {
                    instantiators[config.StartUpLogType] = startUpLogInstantiator;
                }
                var startUpLog = startUpLogInstantiator.GetSingletonInstance(this) as IActinLogger;
                if (startUpLog == null)
                {
                    throw new ApplicationException("The 'StartUp' Log must implement IActinLogger.");
                }
                startUpLogAsActor = startUpLog as Actor;
                log.AddDestination(startUpLog);

                if (startUpLog is ActinStandardLogger && !string.IsNullOrWhiteSpace(config.StandardLogOutputFolder))
                {
                    var standardLogger = startUpLog as ActinStandardLogger;
                    standardLogger.SetClock(this.Clock);
                    standardLogger.SetLogFolderPath(config.StandardLogOutputFolder);
                }
            }

            try {
                //Do manual user start up:
                log.Info("Director Initializing");
                await config.RunBeforeStart(new ActorUtil(null, this.Clock) {
                    Log = log,
                });

                //Do automated DI startup:
                foreach (var a in config.AssembliesToCheckForDI)
                {
                    try {
                        foreach (var t in a.GetTypes())
                        {
                            if (t.HasAttribute <SingletonAttribute>() || t.HasAttribute <InstanceAttribute>())
                            {
                                lock (lockInstantiators) {
                                    if (!instantiators.ContainsKey(t))
                                    {
                                        //If it's already contained, then it was manually added as a Singleton dependency.
                                        //We can't add it again, as when manually added, a singleton instance was provided.
                                        instantiators[t] = new ActinInstantiator(t);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex) {
                        var msg = $"Actin Failed in assembly {a.FullName}. Inner Exception: {ex.Message}";
                        log.Error(msg, ex);
                        await runStartUpLog();

                        throw new Exception(msg, ex);
                    }
                }

                lock (lockInstantiators) {
                    //At this point, we should only have manually added singletons, and attribute marked Singleton or Instance classes.
                    var rootableInstantiators = instantiators.Values.ToList();
                    rootableInstantiators = rootableInstantiators.Where(config.RootActorFilter).ToList();
                    var skipped = new List <ActinInstantiator>();
                    foreach (var instantiator in rootableInstantiators)
                    {
                        try {
                            var skippedBecauseConcreteLineageRequired = !instantiator.Build(t => {
                                if (!this.instantiators.TryGetValue(t, out var dependencyInstantiator))
                                {
                                    dependencyInstantiator = new ActinInstantiator(t);
                                    this.instantiators[t]  = dependencyInstantiator;
                                }
                                return(dependencyInstantiator);
                            });
                            if (skippedBecauseConcreteLineageRequired)
                            {
                                skipped.Add(instantiator);
                            }
                        }
                        catch (Exception ex) {
                            throw new ApplicationException($"Failed to build rootable type {instantiator.Type.Name}: {ex.Message}", ex);
                        }
                    }

                    var skippedAndNeverBuilt = skipped.Where(x => !x.WasBuilt).ToList();
                    if (skippedAndNeverBuilt.Any())
                    {
                        throw new AggregateException(skippedAndNeverBuilt.Select(
                                                         x => new ApplicationException($"{x.Type.Name} has a concrete [Parent] or [Sibling], but its parent was not found in the dependency chain."
                                                                                       + "Most likely you forgot to mark the parent class with a [Singleton] or [Instance] attribute."
                                                                                       + "If the Parent is a Scene, or not always available, then you must instead use [FlexibleParent] or [FlexibleSibling]."
                                                                                       + "Note that the flexible attributes do not do type checking on start-up.")));
                    }

                    foreach (var singletonInstantiator in rootableInstantiators.Where(x => x.IsRootSingleton))
                    {
                        var singleton = singletonInstantiator.GetSingletonInstance(this);
                    }
                }

                if (!TryGetSingleton(config.RuntimeLogType, out var rtLog))
                {
                    throw new ApplicationException($"Actin failed to get a singleton instance of the 'Runtime' log. Ensure you've marked {config.RuntimeLogType.Name} with the Singleton attribute, or manually added it to the Director as a singleton.");
                }
                var rtLogAsIActinLogger = rtLog as IActinLogger;
                if (rtLogAsIActinLogger == null)
                {
                    throw new ApplicationException($"{config.RuntimeLogType} must implement IActinLogger, as it is being used as the 'Runtime' Log.");
                }

                runtimeLog.AddDestination(rtLogAsIActinLogger);
                await config.RunAfterStart(new ActorUtil(null, this.Clock) {
                    Log = new LogDispatcherForActor(runtimeLog, "After Start"),
                });

                return(config);
            }
            catch (Exception ex) when(logFailedStartup(ex))
            {
                //Exception is always unhandled, this is a nicer way to ensure logging before the exception propagates.
                return(null);
            }

            bool logFailedStartup(Exception ex)
            {
                log.Log(new ActinLog {
                    Time        = Clock.Now,
                    Location    = "StartUp",
                    UserMessage = "Actin failed to start.",
                    Details     = ex?.ToString(),
                    Type        = LogType.Error,
                });
                runStartUpLog().Wait();
                return(false);
            }

            async Task runStartUpLog()
            {
                try {
                    if (startUpLogAsActor != null)
                    {
                        var disposeHandle = await startUpLogAsActor.Init(() => new DispatchData {
                            MainLog = new ConsoleLogger(),
                        });

                        if (disposeHandle != null)
                        {
                            lock (lockDisposeHandles) {
                                disposeHandles.Add(disposeHandle);
                            }
                        }
                        await startUpLogAsActor.Run(() => new DispatchData {
                            MainLog = new ConsoleLogger(),
                        });
                    }
                }
                catch {
                    //Nowhere to put this if the log is failing.
                }
            }
        }
Example #3
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);
                }
            }
        }
Example #4
0
 /// <summary>
 /// Get setting path.
 /// </summary>
 /// <returns>Setting path</returns>
 public static string GetPath(string fileName)
 {
     return(ConfigureUtil.GetAppCurrentDirectory().AddDelimiter() + fileName);
 }
Example #5
0
 /// <summary>
 /// Get setting path.
 /// </summary>
 /// <returns>Setting path</returns>
 public static string GetPath()
 {
     return(ConfigureUtil.GetAppCurrentDirectory().AddDelimiter() + Constants.SettingFileName);
 }