Пример #1
0
 protected override async Task OnDispose(ActorUtil util)
 {
     disposedList.ShouldHaveBeenDisposed.Enqueue(this);
     await Task.FromResult(0);
 }
Пример #2
0
 protected override async Task OnInit(ActorUtil util)
 {
     allDependencies.Dependencies.Enqueue(this);
     await Task.FromResult(0);
 }
Пример #3
0
 protected override async Task OnRun(ActorUtil util)
 {
     await Task.FromResult(0);
 }
Пример #4
0
        protected override async Task OnRun(ActorUtil util)
        {
            var cmds = Commands.DequeueAll();

            var parentHasCompiled       = parentFile.CompileStatus == CompileStatus.Compiled;
            var parentExecutableVersion = parentFile.ExecutableVersion;
            var parentWasRecompiled     = parentHasCompiled && parentExecutableVersion != lastKnownExecutableVersion;

            if (parentHasCompiled)
            {
                lastKnownExecutableVersion = parentExecutableVersion;
            }

            var shouldPause         = cmds.Any(x => x == CTestCommand.Cancel);
            var shouldResumeOrForce = !shouldPause && cmds.Any(x => x == CTestCommand.Run);

            var statusWas = this.runStatusAtom.Value;

            this.runStatusAtom.Value = step();

            if (statusWas != RunStatus)
            {
                triggerUpdate();
            }

            await Task.FromResult(0);

            return;

            //This state-machine actor combination which cancels if a particular
            //step stalls for long enough is a nice pattern. I wonder if there's
            //a nice way to abstract this. If putting this in a language, it would
            //be really neat to define the enum inline based on the needs of the actor,
            //and then reference the enum elsewhere.
            RunStatus step()
            {
                switch (statusWas)
                {
                case RunStatus.WaitingOnParent:
                case RunStatus.TimedOut:
                    if (shouldPause)
                    {
                        return(RunStatus.Paused);
                    }
                    else if (parentWasRecompiled || (shouldResumeOrForce && parentHasCompiled))
                    {
                        return(RunStatus.Scheduled);
                    }
                    else
                    {
                        return(statusWas);
                    }

                case RunStatus.Scheduled:
                    if (shouldPause)
                    {
                        return(RunStatus.Paused);
                    }
                    else if (!parentHasCompiled)
                    {
                        return(RunStatus.WaitingOnParent);
                    }
                    else
                    {
                        this.ProcHandle?.Cancel();
                        this.procHandleAtom.Value = null;
                        var originalPath   = parentFile.SourceFile.FilePath;
                        var executablePath = Path.Combine(Path.GetDirectoryName(originalPath), "bin", Path.GetFileNameWithoutExtension(originalPath));
                        var isWindows      = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
                        if (isWindows)
                        {
                            executablePath += ".exe";
                        }
                        //It would be nice if Actin provided a mechanism to automatically
                        //handle this sort of interaction. We want another actor to do something,
                        //and our next action requires the completion of it. The called actor needs
                        //to know if we've canceled the request, and we need to cancel the request
                        //if we go too long waiting for it.
                        processReceiptAtom.Value = processRunner.StartProcess(new ProcStartInfo(
                                                                                  path: executablePath,
                                                                                  workingDirectory: Path.GetDirectoryName(executablePath),
                                                                                  arguments: new string[] { Test.LineNumber.ToString() },
                                                                                  maxRunTime: new TimeSpan(0, 0, 10),
                                                                                  accept: newHandle => {
                            if (newHandle.Id == processReceiptAtom.Value)
                            {
                                this.procHandleAtom.Value = newHandle;
                            }
                            else
                            {
                                newHandle.Cancel();
                            }
                        }
                                                                                  ));
                        startWait();
                        return(RunStatus.WaitingOnProcessStart);
                    }

                case RunStatus.WaitingOnProcessStart:
                    if (shouldPause)
                    {
                        this.processReceiptAtom.Value = Guid.Empty;
                        return(RunStatus.Paused);
                    }
                    else if (ProcHandle != null)
                    {
                        startWait();
                        return(RunStatus.Running);
                    }
                    else if (haveWaited(new TimeSpan(0, 0, 5)))
                    {
                        ProcHandle?.Cancel();
                        return(RunStatus.TimedOut);
                    }
                    else
                    {
                        return(RunStatus.WaitingOnProcessStart);
                    }

                case RunStatus.Running:
                    if (shouldPause)
                    {
                        ProcHandle?.Cancel();
                        return(RunStatus.Paused);
                    }
                    else
                    {
                        var ph = this.ProcHandle;
                        if (haveWaited(new TimeSpan(0, 0, 5)))
                        {
                            return(RunStatus.TimedOut);
                        }
                        else if (ph.Status != ProcessStatus.Finished)
                        {
                            return(RunStatus.Running);
                        }
                        else
                        {
                            lastCompletedRunResultAtom.Value = ph.Result;
                            return(RunStatus.WaitingOnParent);
                        }
                    }

                case RunStatus.Paused:
                    if (shouldResumeOrForce)
                    {
                        return(parentHasCompiled ? RunStatus.Scheduled : RunStatus.WaitingOnParent);
                    }
                    else
                    {
                        return(RunStatus.Paused);
                    }

                default:
                    throw new NotImplementedException(statusWas.ToString("g"));
                }
            }

            void startWait()
            {
                lastWaitStarted = util.Now;
            }

            bool haveWaited(TimeSpan moreThanThis)
            {
                var timeSpentWaiting = util.Now - lastWaitStarted;

                return(timeSpentWaiting > moreThanThis);
            }

            void triggerUpdate()
            {
                sendUpdates.Send_UpdateTest(parentFile.SourceFile.FilePath ?? "", this.Id);
            }
        }
Пример #5
0
 public async Task OnInit(ActorUtil util)
 {
     allDependencies.Dependencies.Enqueue(this);
     await Task.FromResult(0);
 }
Пример #6
0
 protected override async Task OnDispose(ActorUtil util)
 {
     theScene.Disposed.Enqueue(this.Id);
     await Task.FromResult(0);
 }
Пример #7
0
        protected override async Task OnRun(ActorUtil util)
        {
            HashSet <string> rootCandidates   = new HashSet <string>();
            HashSet <string> changeCandidates = new HashSet <string>();

            {
                if (RootSourceFileDetected.TryDequeueAll(out var reportedRootSourceFiles))
                {
                    foreach (var path in reportedRootSourceFiles)
                    {
                        rootCandidates.Add(path);
                        changeCandidates.Add(path);
                    }
                }
                if (AnySourceFileDetectedOrChanged.TryDequeueAll(out var reportedChangedSourceFiles))
                {
                    foreach (var path in reportedChangedSourceFiles)
                    {
                        changeCandidates.Add(path);
                    }
                }
            }

            if (!(rootCandidates.Any() || changeCandidates.Any()))
            {
                return;
            }

            var currentParseTime      = util.Now;
            var activeRootSourceFiles = this.parsedRoots;

            {
                var newRootPaths = rootCandidates.Where(candidatePath => !activeRootSourceFiles.Any(file => file.FilePath == candidatePath)).ToArray();
                foreach (var rootPath in newRootPaths)
                {
                    var errorMessagesAtom = new Atom <ImmutableList <string> >(ImmutableList.Create <string>());
                    var result            = await CTestSourceFile.Create(rootPath, currentParseTime, errorMessagesAtom);

                    activeRootSourceFiles = activeRootSourceFiles.Add(result);
                    foreach (var message in errorMessagesAtom.Value)
                    {
                        util.Log.Error(message);
                    }
                }
            }

            {
                var rootsCopy = activeRootSourceFiles;
                foreach (var root in rootsCopy)
                {
                    if (root.ParseTime == currentParseTime)
                    {
                        //We already recompiled this round.
                        continue;
                    }
                    if (root.ReferencesPaths(changeCandidates))
                    {
                        var errorMessagesAtom = new Atom <ImmutableList <string> >(ImmutableList.Create <string>());
                        var result            = await CTestSourceFile.Create(root.FilePath, currentParseTime, errorMessagesAtom);

                        activeRootSourceFiles = activeRootSourceFiles.Replace(root, result);
                        foreach (var message in errorMessagesAtom.Value)
                        {
                            util.Log.Error(message);
                        }
                    }
                }
            }

            //Remove any missing root files:
            activeRootSourceFiles = activeRootSourceFiles.Where(x => x.Exists).ToImmutableList();
            this.parsedRoots      = activeRootSourceFiles; //<== If anything external wants to look at these

            activeTestFiles.LatestRootFiles.Enqueue(activeRootSourceFiles);

            var allUniqueFiles = new HashSet <string>();

            foreach (var root in activeRootSourceFiles)
            {
                var leaves = root.Leaves();
                foreach (var leaf in leaves)
                {
                    foreach (var path in leaf.Lineage)
                    {
                        allUniqueFiles.Add(path);
                    }
                }
            }

            fileWatcher.AllDirectoriesToWatch.Enqueue(allUniqueFiles.Select(x => Path.GetDirectoryName(x)).Distinct().ToImmutableList());
        }
Пример #8
0
        /// <summary>
        /// Returns a description, what she's wearing
        /// </summary>
        public string GetClothesDescription(List <Clothing> clothes)
        {
            string output     = Name + " ";
            bool   topless    = false;
            bool   bottomless = false;
            bool   barefoot   = false;
            bool   onepiece   = false;

            long[] visibleClothes = new long[2];
            long[] footwear       = new long[2];

            //Examine her clothes
            if (WornClothes[2] != 0)
            {
                visibleClothes[0] = WornClothes[2];
                onepiece          = true;
            }
            else
            {
                if (WornClothes[0] != 0)
                {
                    visibleClothes[0] = WornClothes[0];
                }
                else
                {
                    if (WornClothes[3] != 0)
                    {
                        visibleClothes[0] = WornClothes[3];
                    }
                    else
                    {
                        topless = true;
                    }
                }
                if (WornClothes[1] != 0)
                {
                    visibleClothes[1] = WornClothes[1];
                }
                else
                {
                    if (WornClothes[4] != 0)
                    {
                        visibleClothes[1] = WornClothes[4];
                    }
                    else
                    {
                        bottomless = true;
                    }
                }
            }

            //Examine her footwear
            if (WornClothes[5] == 0 && WornClothes[6] == 0)
            {
                barefoot = true;
            }
            else
            {
                footwear[0] = WornClothes[5];
                footwear[1] = WornClothes[6];
            }

            //Build output string
            if (topless && bottomless && barefoot)
            {
                return(String.Format("{0} doesn't wear any clothes at all.", Name));
            }
            else
            {
                if (onepiece)
                {
                    output += string.Format("wears {0}", ActorUtil.GetClothingById(clothes, visibleClothes[0]).GetClothingDescription());
                }
                else if (topless || bottomless)
                {
                    output += "only wears ";
                    if (visibleClothes[0] != 0)
                    {
                        output += ActorUtil.GetClothingById(clothes, visibleClothes[0]).GetClothingDescription();
                    }
                    else
                    {
                        output += ActorUtil.GetClothingById(clothes, visibleClothes[1]).GetClothingDescription();
                    }
                }
                else
                {
                    output += String.Format("wears {0}, {1}", ActorUtil.GetClothingById(clothes, visibleClothes[0]).GetClothingDescription(), ActorUtil.GetClothingById(clothes, visibleClothes[1]).GetClothingDescription());
                    if (barefoot)
                    {
                        output += " and is barefoot.";
                        return(output);
                    }
                }
                if (barefoot)
                {
                    output += " and is barefoot.";
                    return(output);
                }
                else
                {
                    if (footwear[0] != 0 && footwear[1] != 0)
                    {
                        output += String.Format(", {0} and {1}", ActorUtil.GetClothingById(clothes, footwear[0]).GetClothingDescription(), ActorUtil.GetClothingById(clothes, footwear[1]).GetClothingDescription());
                    }
                    else
                    {
                        if (footwear[0] != 0)
                        {
                            output += String.Format(" and {0}.", ActorUtil.GetClothingById(clothes, footwear[0]).GetClothingDescription());
                            return(output);
                        }
                        else
                        {
                            output += String.Format(" and {0}.", ActorUtil.GetClothingById(clothes, footwear[0]).GetClothingDescription());
                            return(output);
                        }
                    }
                }
            }

            return(output);
        }
Пример #9
0
 protected override async Task OnInit(ActorUtil util)
 {
     theScene.Initialized.Enqueue(this.Id);
     await Task.FromResult(0);
 }
        protected override async Task OnRun(ActorUtil util)
        {
            await Task.FromResult(0);

            var userSettings = settings.UserSettings;
            var paths        = userSettings.TestDirectories;

            if (paths == null || !paths.Any())
            {
                fileWatcher.AllDirectoriesToWatch.Enqueue(ImmutableList.Create <string>());
            }
            foreach (var path in paths)
            {
                try {
                    if (!Directory.Exists(path))
                    {
                        util.Log.RealTime($"Path not found: {path}");
                        continue;
                    }
                    if (!watchers.ContainsKey(path))
                    {
                        var watcher = new FileSystemWatcher(path);
                        foreach (var pattern in settings.UserSettings.TestRootPatterns)
                        {
                            watcher.Filters.Add(pattern);
                        }
                        watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime | NotifyFilters.FileName;

                        void enqueue(object sender, FileSystemEventArgs e)
                        {
                            switch (e)
                            {
                            case RenamedEventArgs re:
                                parser.RootSourceFileDetected.Enqueue(re.OldFullPath);
                                parser.RootSourceFileDetected.Enqueue(re.FullPath);
                                break;

                            case FileSystemEventArgs fe:
                                parser.RootSourceFileDetected.Enqueue(fe.FullPath);
                                break;
                            }
                        }
                        watcher.Changed += enqueue;
                        watcher.Created += enqueue;
                        watcher.Deleted += enqueue;
                        watcher.Renamed += enqueue;

                        watcher.EnableRaisingEvents = true;
                        watchers.Add(path, watcher);

                        //Search for the files for the first time:
                        foreach (var pattern in userSettings.TestRootPatterns)
                        {
                            try {
                                var initialRootFiles = Directory.GetFiles(path, pattern);
                                parser.RootSourceFileDetected.EnqueueRange(initialRootFiles);
                            }
                            catch (Exception ex) {
                                util.Log.RealTime($"Failed to process root test pattern {pattern} in directory {path}", ex);
                            }
                        }
                    }
                }
                catch (Exception ex) {
                    util.Log.RealTime($"Failed to process root test directory {path}", ex);
                }
            }

            var watcherList = watchers.ToList();

            foreach (var watcher in watcherList)
            {
                if (!paths.Contains(watcher.Key))
                {
                    watchers.Remove(watcher.Key);
                    watcher.Value.Dispose();
                }
            }
        }
Пример #11
0
 protected async override Task OnRun(ActorUtil util)
 {
     System.Globalization.CultureInfo.CurrentCulture.ClearCachedData();
     await Task.FromResult(0);
 }
Пример #12
0
        protected override async Task <IEnumerable <Role> > CastActors(ActorUtil util, Dictionary <int, CTests_AvailableTest> myActors)
        {
            var mySourceFile = parent.RootSourceFiles.FirstOrDefault(x => x.FilePath == this.Id);

            if (mySourceFile.FilePath == null)
            {
                this.Dispose();
                triggerUpdate();
                return(null);
            }

            if (sourceFileAtom.Value.ParseTime != mySourceFile.ParseTime)
            {
                sourceFileAtom.Value = mySourceFile;
                triggerUpdate();
            }

            var compileStatusWas = this.CompileStatus;

            this.compileStatusAtom.Value = step();

            if (compileStatusWas != CompileStatus)
            {
                triggerUpdate();
            }

            await Task.FromResult(0);

            return(mySourceFile.Tests.Select(x => new Role {
                Id = x.TestNumber,
            }));

            CompileStatus step()
            {
                switch (compileStatusWas)
                {
                case CompileStatus.Modified:
                    executableVersionAtom.Value = mySourceFile.ParseTime;
                    var us = settings.UserSettings;
                    try {
                        Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(mySourceFile.FilePath), "bin"));
                    }
                    catch { }
                    this.ProcHandle?.Cancel();
                    this.procHandleAtom.Value = null;
                    processReceiptAtom.Value  = processRunner.StartProcess(new ProcStartInfo(
                                                                               path: us.CompilerPath,
                                                                               workingDirectory: Path.GetDirectoryName(mySourceFile.FilePath),
                                                                               arguments: us.GetProcessedCompileArguments(mySourceFile.FilePath),
                                                                               maxRunTime: new TimeSpan(0, 0, 10),
                                                                               accept: newHandle => {
                        if (newHandle.Id == processReceiptAtom.Value)
                        {
                            this.procHandleAtom.Value = newHandle;
                        }
                        else
                        {
                            newHandle.Cancel();
                        }
                    }
                                                                               ));
                    startWait();
                    return(CompileStatus.WaitingOnProcessStart);

                case CompileStatus.WaitingOnProcessStart:
                    if (ProcHandle != null)
                    {
                        startWait();
                        return(CompileStatus.Compiling);
                    }
                    else if (haveWaited(new TimeSpan(0, 0, 5)))
                    {
                        ProcHandle?.Cancel();
                        return(CompileStatus.TimedOut);
                    }
                    else
                    {
                        return(CompileStatus.WaitingOnProcessStart);
                    }

                case CompileStatus.Compiling:
                    var ph = this.ProcHandle;
                    if (haveWaited(new TimeSpan(0, 0, 5)))
                    {
                        return(CompileStatus.TimedOut);
                    }
                    else if (ph.Status != ProcessStatus.Finished)
                    {
                        return(CompileStatus.Compiling);
                    }
                    else
                    {
                        var result = ph.Result;
                        lastCompileResultAtom.Value = result;
                        if (result.GracefulExit && result.ExitCode == 0)
                        {
                            return(CompileStatus.Compiled);
                        }
                        else
                        {
                            return(CompileStatus.Failed);
                        }
                    }

                case CompileStatus.Failed:
                case CompileStatus.TimedOut:
                case CompileStatus.Compiled:
                    if (executableVersionAtom.Value != mySourceFile.ParseTime)
                    {
                        return(CompileStatus.Modified);
                    }
                    else
                    {
                        return(compileStatusWas);
                    }

                default:
                    throw new NotImplementedException(compileStatusWas.ToString("g"));
                }
            }

            void startWait()
            {
                lastWaitStarted = util.Now;
            }

            bool haveWaited(TimeSpan moreThanThis)
            {
                var timeSpentWaiting = util.Now - lastWaitStarted;

                return(timeSpentWaiting > moreThanThis);
            }

            void triggerUpdate()
            {
                sendUpdates.Send_UpdateTestsFile(mySourceFile.FilePath ?? "");
            }
        }
Пример #13
0
 protected async override Task OnRun(ActorUtil util)
 {
     SelfRan.Enqueue(0);
     await Task.FromResult(0);
 }
Пример #14
0
 protected override async Task OnRun(ActorUtil util)
 {
     await UpdateAndReturnIfDbIsUp();
 }
Пример #15
0
 protected override Task OnRun(ActorUtil util)
 {
     return(Task.FromResult(0));
 }
Пример #16
0
 protected override Task OnDispose(ActorUtil util)
 {
     cTokenSource.Cancel();
     return(Task.FromResult(0));
 }