static void Main() { DateTime time1 = DateTime.Now; s_channel = new Channel <int>(); MicroThread t2 = new MicroThread(run2); t2.Start(); MicroThread t3 = new MicroThread(run2); t3.Start(); MicroThread t1 = new MicroThread(run1); t1.Start(); Console.WriteLine("Starting producer/consumer test, loops {0}", s_loops); Scheduler.Run(); DateTime time2 = DateTime.Now; Console.WriteLine("total {0}", res); Console.WriteLine("time {0}ms", (time2 - time1).TotalMilliseconds); Console.WriteLine("END"); }
protected MicroThread[] TestBase(string testName, BaseTests baseTests, Func <Action, Task> asyncFunction, int parallelCount, MicroThreadFlags flags = MicroThreadFlags.None) { var scheduler = new Scheduler(); int completed = 0; var microThreads = new MicroThread[parallelCount]; // Run two microthreads at the same time for (int i = 0; i < parallelCount; ++i) { microThreads[i] = scheduler.Add(() => asyncFunction(() => { Interlocked.Increment(ref completed); CheckStackForSchedulerStep(); }), flags); } // Simulation of main loop for (int i = 0; i < 1000 && scheduler.MicroThreads.Count() > 0; ++i) { baseTests.SharedCounter = i; scheduler.Run(); Thread.Sleep(10); } // Check both microthreads completed Assert.That(completed, Is.EqualTo(parallelCount)); return(microThreads); }
//static long s_totalYields = 0; static int Main(string[] args) { if (args.Length != 2) { Console.WriteLine("usage: YieldTest <numthreads> <numloops>"); return(1); } s_threads = Int32.Parse(args[0]); s_loops = Int32.Parse(args[1]); for (int i = 0; i < s_threads; i++) { MicroThread t = new MicroThread(Run); t.Start(); } DateTime t1 = DateTime.Now; Scheduler.Run(); DateTime t2 = DateTime.Now; TimeSpan ts = t2 - t1; //Console.WriteLine("Total yields {0}", s_totalYields); Console.WriteLine("{0} threads * {1} loops = {2} yields in {3:F2}s, {4:F0} yields/s", s_threads, s_loops, s_threads * s_loops, ts.TotalSeconds, (s_threads * s_loops) / ts.TotalSeconds); /* * long mem = System.GC.GetTotalMemory(false); * Console.WriteLine("Mem {0:F2}M", mem / 1000000.0); */ return(0); }
private void AddMicroThread(MicroThread microThread) { Dispatcher.BeginInvoke((Action) delegate { microThreads.Add(new MicroThreadViewModel(microThread)); }, null); }
static void Main(string[] args) { if (args.Length == 0 || args[0] == "server") { MicroThread pt = new MicroThread(ServerPrintRun); pt.Start(); Server.s_bufferSize = s_blockSize; MicroThread t = new MicroThread(Server.ListenRun); t.Start(); Scheduler.Run(); } else { Console.WriteLine("Starting {0} threads, sending {1} {2} byte blocks", s_threads, s_blocks, s_blockSize); MicroThread pt = new MicroThread(ClientPrintRun); pt.Start(); for (int i = 0; i < s_threads; i++) { Client c = new Client(s_blocks, s_blockSize); MicroThread t = new MicroThread(c.Run); t.Start(); } DateTime t1 = DateTime.Now; Scheduler.Run(); DateTime t2 = DateTime.Now; Console.WriteLine(); Console.WriteLine("TOTAL {0} MB/s", (Client.s_totalBlocksSent / 1000.0 / 1000.0 * s_blockSize) / ((TimeSpan)(t2 - t1)).TotalSeconds); } }
public void MicroThreadTest() { MicroThread microA = new MicroThread(); MicroThread microB = new MicroThread(); microA.MainThread.Mark(); microA.MyThread.Mark(); microB.MainThread.Mark(); microB.MyThread.Mark(); Assert.AreEqual(false, microA.Done); Assert.AreEqual(false, microB.Done); microA.DoWork(() => { int count = 0; while (count < 100) { ++count; if (count % 10 == 0) { microA.Yield(); } } }); MicroBJob jobB = new MicroBJob(); jobB.MicroThread = microB; microB.DoWork(jobB.Work); Assert.AreEqual(false, microA.Done); Assert.AreEqual(false, microB.Done); int yields = 0; while (yields < 20) { if (!microA.Done) { microA.Resume(); } if (!microB.Done) { microB.Resume(); } if (microA.Done && microB.Done) { break; } ++yields; } Assert.AreEqual(true, microA.Done); Assert.AreEqual(true, microB.Done); Assert.AreEqual(100, jobB.Count); Assert.AreEqual(9, yields); }
static void Main() { MicroThread t = new MicroThread(MainRun); t.Start(); Scheduler.Run(); }
static void Main() { MicroThread t1 = new MicroThread(Run1); MicroThread t2 = new MicroThread(Run2); t1.Start(); t2.Start(); Scheduler.Run(); }
public MicroThreadViewModel(MicroThread microThread) { if (microThread == null) throw new ArgumentNullException("microThread"); if (microThread.Scheduler == null) throw new ArgumentException("Invalid Scheduler in MicroThread " + microThread.Id); this.microThread = microThread; // New MicroThread system doesn't have any PropertyChanged event yet. throw new NotImplementedException(); //this.microThread.Scheduler.MicroThreadStateChanged += OnMicroThreadStateChanged; }
private void RetryableMatchEvent(EventBean theEvent, ICollection <FilterHandle> matches) { // Install lock backoff exception handler that retries the evaluation. try { _eventTypeIndex.MatchEvent(theEvent, matches); } catch (FilterLockBackoffException ex) { // retry on lock back-off // lock-backoff may occur when stateful evaluations take place such as bool expressions that are subqueries // statements that contain subqueries in pattern filter expression can themselves modify filters, leading to a theoretically possible deadlock long delayNs = 10; while (true) { try { // yield try { Thread.Sleep(0); } catch (ThreadInterruptedException e) { Thread.CurrentThread.Interrupt(); } // delay MicroThread.SleepNano(delayNs); if (delayNs < 1000000000) { delayNs = delayNs * 2; } // evaluate matches.Clear(); _eventTypeIndex.MatchEvent(theEvent, matches); break; } catch (FilterLockBackoffException ex2) { // retried } } } }
static void MainRun() { int started = 0; while (true) { if (Scheduler.ThreadCount < 100) { MicroThread t = new MicroThread(Work); t.Start(); started++; } Console.WriteLine("Threads {0}, started {1}", Scheduler.ThreadCount, started); Scheduler.Yield(); } }
public MicroThreadViewModel(MicroThread microThread) { if (microThread == null) { throw new ArgumentNullException("microThread"); } if (microThread.Scheduler == null) { throw new ArgumentException("Invalid Scheduler in MicroThread " + microThread.Id); } this.microThread = microThread; // New MicroThread system doesn't have any PropertyChanged event yet. throw new NotImplementedException(); //this.microThread.Scheduler.MicroThreadStateChanged += OnMicroThreadStateChanged; }
static void Main() { DateTime time1 = DateTime.Now; MicroThread t = new MicroThread(loop); t.Start(); Console.WriteLine("Starting yield test, loops {0}", s_loops); Scheduler.Run(); DateTime time2 = DateTime.Now; Console.WriteLine("END {0}", res); TimeSpan ts = time2 - time1; Console.WriteLine("time {0}ms", ts.TotalMilliseconds); }
static int Main(string[] args) { if (args.Length != 1) { Console.WriteLine("usage: SleepTest <numthreads>"); return(1); } s_threads = Int32.Parse(args[0]); for (int i = 0; i < s_threads; i++) { Sleeper s = new Sleeper(); MicroThread t = new MicroThread(s.Run); t.Start(); } Scheduler.Run(); return(0); }
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); MyForm f = new MyForm(); f.Show(); new MicroThread(WindowRun).Start(); for (int i = 0; i < 200; i++) { Dot d = new Dot(i, 0, Color.Red, f); MicroThread t = new MicroThread(d.Run); t.Start(); } Scheduler.Run(); // Application.Run(f); }
public static void ListenRun() { MicroSocket listenSocket = new MicroSocket(); IPEndPoint ep = new IPEndPoint(IPAddress.Any, 12345); listenSocket.Bind(ep); listenSocket.Listen(10); while (true) { MicroSocket socket = listenSocket.Accept(); //Console.WriteLine("Accepted a new socket"); //Console.Write("."); s_connectedSockets++; Server server = new Server(socket); MicroThread t = new MicroThread(server.SocketRun); t.Start(); } }
private BuildResultCode BuildSlave() { // Mount build path ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory); VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath); // Open WCF channel with master builder var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { SendTimeout = TimeSpan.FromSeconds(300.0), MaxReceivedMessageSize = int.MaxValue }; var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(builderOptions.SlavePipe)); try { RegisterRemoteLogger(processBuilderRemote); // Make sure to laod all assemblies containing serializers // TODO: Review how costly it is to do so, and possibily find a way to restrict what needs to be loaded (i.e. only app plugins?) foreach (var assemblyLocation in processBuilderRemote.GetAssemblyContainerLoadedAssemblies()) { AssemblyContainer.Default.LoadAssemblyFromPath(assemblyLocation, builderOptions.Logger); } // Create scheduler var scheduler = new Scheduler(); var status = ResultStatus.NotProcessed; // Schedule command string buildPath = builderOptions.BuildDirectory; Builder.OpenObjectDatabase(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName); var logger = builderOptions.Logger; MicroThread microthread = scheduler.Add(async() => { // Deserialize command and parameters Command command = processBuilderRemote.GetCommandToExecute(); // Run command var inputHashes = FileVersionTracker.GetDefault(); var builderContext = new BuilderContext(inputHashes, null); var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger); MicrothreadLocalDatabases.MountDatabase(commandContext.GetOutputObjectsGroups()); command.PreCommand(commandContext); status = await command.DoCommand(commandContext); command.PostCommand(commandContext, status); // Returns result to master builder processBuilderRemote.RegisterResult(commandContext.ResultEntry); }); while (true) { scheduler.Run(); // Exit loop if no more micro threads lock (scheduler.MicroThreads) { if (!scheduler.MicroThreads.Any()) { break; } } Thread.Sleep(0); } // Rethrow any exception that happened in microthread if (microthread.Exception != null) { builderOptions.Logger.Fatal(microthread.Exception.ToString()); return(BuildResultCode.BuildError); } if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful) { return(BuildResultCode.Successful); } return(BuildResultCode.BuildError); } finally { // Close WCF channel // ReSharper disable SuspiciousTypeConversion.Global ((IClientChannel)processBuilderRemote).Close(); // ReSharper restore SuspiciousTypeConversion.Global } }
private BuildResultCode BuildSlave() { // Mount build path ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory); VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath); // Open ServiceWire Client Channel using (var client = new NpClient <IProcessBuilderRemote>(new NpEndPoint(builderOptions.SlavePipe), new StrideServiceWireSerializer())) { RegisterRemoteLogger(client); // Make sure to laod all assemblies containing serializers // TODO: Review how costly it is to do so, and possibily find a way to restrict what needs to be loaded (i.e. only app plugins?) foreach (var assemblyLocation in client.Proxy.GetAssemblyContainerLoadedAssemblies()) { AssemblyContainer.Default.LoadAssemblyFromPath(assemblyLocation, builderOptions.Logger); } // Create scheduler var scheduler = new Scheduler(); var status = ResultStatus.NotProcessed; // Schedule command string buildPath = builderOptions.BuildDirectory; Builder.OpenObjectDatabase(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName); var logger = builderOptions.Logger; MicroThread microthread = scheduler.Add(async() => { // Deserialize command and parameters Command command = client.Proxy.GetCommandToExecute(); // Run command var inputHashes = FileVersionTracker.GetDefault(); var builderContext = new BuilderContext(inputHashes, null); var commandContext = new RemoteCommandContext(client.Proxy, command, builderContext, logger); MicrothreadLocalDatabases.MountDatabase(commandContext.GetOutputObjectsGroups()); command.PreCommand(commandContext); status = await command.DoCommand(commandContext); command.PostCommand(commandContext, status); // Returns result to master builder client.Proxy.RegisterResult(commandContext.ResultEntry); }); while (true) { scheduler.Run(); // Exit loop if no more micro threads lock (scheduler.MicroThreads) { if (!scheduler.MicroThreads.Any()) { break; } } Thread.Sleep(0); } // Rethrow any exception that happened in microthread if (microthread.Exception != null) { builderOptions.Logger.Fatal(microthread.Exception.ToString()); return(BuildResultCode.BuildError); } if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful) { return(BuildResultCode.Successful); } return(BuildResultCode.BuildError); } }
private BuildResultCode BuildSlave() { // Mount build path ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory); PrepareDatabases(); VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath); // Open WCF channel with master builder var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { SendTimeout = TimeSpan.FromSeconds(300.0) }; var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(builderOptions.SlavePipe)); try { RegisterRemoteLogger(processBuilderRemote); // Create scheduler var scheduler = new Scheduler(); var status = ResultStatus.NotProcessed; // Schedule command string buildPath = builderOptions.BuildDirectory; string buildProfile = builderOptions.BuildProfile; Builder.SetupBuildPath(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName); var logger = builderOptions.Logger; MicroThread microthread = scheduler.Add(async() => { // Deserialize command and parameters Command command = processBuilderRemote.GetCommandToExecute(); BuildParameterCollection parameters = processBuilderRemote.GetBuildParameters(); // Run command var inputHashes = FileVersionTracker.GetDefault(); var builderContext = new BuilderContext(buildPath, buildProfile, inputHashes, parameters, 0, null); var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger); IndexFileCommand.MountDatabase(commandContext.GetOutputObjectsGroups()); command.PreCommand(commandContext); status = await command.DoCommand(commandContext); command.PostCommand(commandContext, status); // Returns result to master builder processBuilderRemote.RegisterResult(commandContext.ResultEntry); }); while (true) { scheduler.Run(); // Exit loop if no more micro threads lock (scheduler.MicroThreads) { if (!scheduler.MicroThreads.Any()) { break; } } Thread.Sleep(0); } // Rethrow any exception that happened in microthread if (microthread.Exception != null) { builderOptions.Logger.Fatal(microthread.Exception.ToString()); return(BuildResultCode.BuildError); } if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful) { return(BuildResultCode.Successful); } return(BuildResultCode.BuildError); } finally { // Close WCF channel // ReSharper disable SuspiciousTypeConversion.Global ((IClientChannel)processBuilderRemote).Close(); // ReSharper restore SuspiciousTypeConversion.Global } }
private void ScheduleBuildStep(BuilderContext builderContext, BuildStep instigator, BuildStep buildStep, IDictionary <string, string> variables) { if (buildStep.ExecutionId == 0) { if (buildStep.Parent != null && buildStep.Parent != instigator) { throw new InvalidOperationException("Scheduling a BuildStep with a different instigator that its parent"); } if (buildStep.Parent == null) { buildStep.Parent = instigator; } // Compute content dependencies before scheduling the build GenerateDependencies(buildStep); // TODO: Big review of the log infrastructure of CompilerApp & BuildEngine! // Create a logger that redirects to various places (BuildStep.Logger, timestampped log, global log, etc...) var buildStepLogger = new BuildStepLogger(buildStep, Logger, startTime); var logger = (Logger)buildStepLogger; // Apply user-registered callbacks to the logger buildStep.TransformExecuteContextLogger?.Invoke(ref logger); // Create execute context var executeContext = new ExecuteContext(this, builderContext, buildStep, logger) { Variables = new Dictionary <string, string>(variables) }; //buildStep.ExpandStrings(executeContext); if (runMode == Mode.Build) { MicroThread microThread = scheduler.Create(); // Set priority from this build step, if we have one. if (buildStep.Priority.HasValue) { microThread.Priority = buildStep.Priority.Value; } buildStep.ExecutionId = microThread.Id; microThread.Name = buildStep.ToString(); // Default: // Schedule continuations as early as possible to help EnumerableBuildStep finish when all its task are finished. // Otherwise, it would wait for all leaf to finish first before finishing parent EnumerableBuildStep. // This should also reduce memory usage, and might improve cache coherency as well. microThread.ScheduleMode = ScheduleMode.First; microThread.Start(async() => { // Wait for prerequisites await Task.WhenAll(buildStep.PrerequisiteSteps.Select(x => x.ExecutedAsync()).ToArray()); // Check for failed prerequisites var status = ResultStatus.NotProcessed; if (buildStep.ArePrerequisitesSuccessful) { try { var outputObjectsGroups = executeContext.GetOutputObjectsGroups(); MicrothreadLocalDatabases.MountDatabase(outputObjectsGroups); // Execute status = await buildStep.Execute(executeContext, builderContext); } catch (TaskCanceledException e) { // Benlitz: I'm NOT SURE this is the correct explanation, it might be a more subtle race condition, but I can't manage to reproduce it again executeContext.Logger.Warning("A child task of build step " + buildStep + " triggered a TaskCanceledException that was not caught by the parent task. The command has not handled cancellation gracefully."); executeContext.Logger.Warning(e.Message); status = ResultStatus.Cancelled; } catch (Exception e) { executeContext.Logger.Error("Exception in command " + buildStep + ": " + e); status = ResultStatus.Failed; } finally { MicrothreadLocalDatabases.UnmountDatabase(); // Ensure the command set at least the result status if (status == ResultStatus.NotProcessed) { throw new InvalidDataException("The build step " + buildStep + " returned ResultStatus.NotProcessed after completion."); } } if (microThread.Exception != null) { executeContext.Logger.Error("Exception in command " + buildStep + ": " + microThread.Exception); status = ResultStatus.Failed; } } else { status = ResultStatus.NotTriggeredPrerequisiteFailed; } //if (completedTask.IsCanceled) //{ // completedStep.Status = ResultStatus.Cancelled; //} var logType = LogMessageType.Info; string logText = null; switch (status) { case ResultStatus.Successful: logType = LogMessageType.Verbose; logText = "BuildStep {0} was successful.".ToFormat(buildStep.ToString()); break; case ResultStatus.Failed: logType = LogMessageType.Error; logText = "BuildStep {0} failed.".ToFormat(buildStep.ToString()); break; case ResultStatus.NotTriggeredPrerequisiteFailed: logType = LogMessageType.Error; logText = "BuildStep {0} failed of previous failed prerequisites.".ToFormat(buildStep.ToString()); break; case ResultStatus.Cancelled: logType = LogMessageType.Warning; logText = "BuildStep {0} cancelled.".ToFormat(buildStep.ToString()); break; case ResultStatus.NotTriggeredWasSuccessful: logType = LogMessageType.Verbose; logText = "BuildStep {0} is up-to-date and has been skipped".ToFormat(buildStep.ToString()); break; case ResultStatus.NotProcessed: throw new InvalidDataException("BuildStep has neither succeeded, failed, nor been cancelled"); } if (logText != null) { var logMessage = new LogMessage(null, logType, logText); executeContext.Logger.Log(logMessage); } buildStep.RegisterResult(executeContext, status); stepCounter.AddStepResult(status); }); } else { buildStep.Clean(executeContext, builderContext, runMode == Mode.CleanAndDelete); } } }
public void MicroThreadTest() { MicroThread microA = new MicroThread(); MicroThread microB = new MicroThread(); microA.MainThread.Mark(); microA.MyThread.Mark(); microB.MainThread.Mark(); microB.MyThread.Mark(); Assert.AreEqual(false, microA.Done); Assert.AreEqual(false, microB.Done); microA.DoWork(() => { int count = 0; while (count < 100) { ++count; if (count % 10 == 0) { microA.Yield(); } } }); MicroBJob jobB = new MicroBJob(); jobB.MicroThread = microB; microB.DoWork(jobB.Work); Assert.AreEqual(false, microA.Done); Assert.AreEqual(false, microB.Done); int yields = 0; while (yields < 20) { if (!microA.Done) microA.Resume(); if (!microB.Done) microB.Resume(); if (microA.Done && microB.Done) break; ++yields; } Assert.AreEqual(true, microA.Done); Assert.AreEqual(true, microB.Done); Assert.AreEqual(100, jobB.Count); Assert.AreEqual(9, yields); }
public static void AddTask(this ScriptComponent script, Func <Task> task, long priority = 0L) { MicroThread t = script.Script.AddTask(task, priority); script.Entity.GetOrCreate <TaskDisposer>().Tasks.Add(t); }
private void OnRunScriptCommand() { MicroThread mt = AssemblyParent.Parent.EngineContext.ScriptManager.RunScript(scriptEntry, null); MicroThread = new MicroThreadViewModel(mt); }
private void ScheduleBuildStep(BuilderContext builderContext, BuildStep instigator, BuildStep buildStep, IDictionary <string, string> variables) { if (buildStep.ExecutionId == 0) { if (buildStep.Parent != null && buildStep.Parent != instigator) { throw new InvalidOperationException("Scheduling a BuildStep with a different instigator that its parent"); } if (buildStep.Parent == null) { buildStep.Parent = instigator; } var executeContext = new ExecuteContext(this, builderContext, buildStep) { Variables = new Dictionary <string, string>(variables) }; //buildStep.ExpandStrings(executeContext); if (runMode == Mode.Build) { MicroThread microThread = scheduler.Create(); // Find priority from this build step, or one of its parent. var buildStepPriority = buildStep; while (buildStepPriority != null) { if (buildStepPriority.Priority.HasValue) { microThread.Priority = buildStepPriority.Priority.Value; break; } buildStepPriority = buildStepPriority.Parent; } buildStep.ExecutionId = microThread.Id; foreach (var threadMonitor in threadMonitors) { threadMonitor.RegisterBuildStep(buildStep, ((BuildStepLogger)executeContext.Logger).StepLogger); } microThread.Name = buildStep.ToString(); // Default: // Schedule continuations as early as possible to help EnumerableBuildStep finish when all its task are finished. // Otherwise, it would wait for all leaf to finish first before finishing parent EnumerableBuildStep. // This should also reduce memory usage, and might improve cache coherency as well. microThread.ScheduleMode = ScheduleMode.First; microThread.Start(async() => { // Wait for prerequisites await Task.WhenAll(buildStep.PrerequisiteSteps.Select(x => x.ExecutedAsync()).ToArray()); // Check for failed prerequisites var status = ResultStatus.NotProcessed; if (buildStep.ArePrerequisitesSuccessful) { try { IndexFileCommand.MountDatabases(executeContext); // Execute status = await buildStep.Execute(executeContext, builderContext); } catch (TaskCanceledException e) { // Benlitz: I'm NOT SURE this is the correct explanation, it might be a more subtle race condition, but I can't manage to reproduce it again executeContext.Logger.Warning("A child task of build step " + buildStep + " triggered a TaskCanceledException that was not caught by the parent task. The command has not handled cancellation gracefully."); executeContext.Logger.Warning(e.Message); status = ResultStatus.Cancelled; } catch (Exception e) { executeContext.Logger.Error("Exception in command " + buildStep + ": " + e); status = ResultStatus.Failed; } finally { IndexFileCommand.UnmountDatabases(executeContext); // Ensure the command set at least the result status if (status == ResultStatus.NotProcessed) { throw new InvalidDataException("The build step " + buildStep + " returned ResultStatus.NotProcessed after completion."); } } if (microThread.Exception != null) { executeContext.Logger.Error("Exception in command " + buildStep + ": " + microThread.Exception); status = ResultStatus.Failed; } } else { status = ResultStatus.NotTriggeredPrerequisiteFailed; } buildStep.RegisterResult(executeContext, status); stepCounter.AddStepResult(status); //if (completedTask.IsCanceled) //{ // completedStep.Status = ResultStatus.Cancelled; //} var logType = LogMessageType.Info; string logText = null; switch (buildStep.Status) { case ResultStatus.Successful: logType = LogMessageType.Info; logText = "BuildStep {0} was successful.".ToFormat(buildStep.ToString()); break; case ResultStatus.Failed: logType = LogMessageType.Error; logText = "BuildStep {0} failed.".ToFormat(buildStep.ToString()); break; case ResultStatus.Cancelled: logType = LogMessageType.Warning; logText = "BuildStep {0} cancelled.".ToFormat(buildStep.ToString()); break; case ResultStatus.NotProcessed: throw new InvalidDataException("BuildStep has neither succeeded, failed, nor been cancelled"); } if (logText != null) { var logMessage = new LogMessage(buildStep.Module, logType, logText); executeContext.Logger.Log(logMessage); } }); } else { buildStep.Clean(executeContext, builderContext, runMode == Mode.CleanAndDelete); } } }
public static BuildResultCode BuildSlave(BuilderOptions options) { // Mount build path ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(options.BuildDirectory); PrepareDatabases(options); try { VirtualFileSystem.CreateDirectory("/data/"); VirtualFileSystem.CreateDirectory("/data/db/"); } catch (Exception) { throw new OptionException("Invalid Build database path", "database"); } // Open WCF channel with master builder var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { SendTimeout = TimeSpan.FromSeconds(300.0) }; var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(options.SlavePipe)); try { RegisterRemoteLogger(processBuilderRemote); // Create scheduler var scheduler = new Scheduler(); var status = ResultStatus.NotProcessed; // Schedule command string buildPath = options.BuildDirectory; Logger logger = options.Logger; MicroThread microthread = scheduler.Add(async() => { // Deserialize command and parameters Command command = processBuilderRemote.GetCommandToExecute(); BuildParameterCollection parameters = processBuilderRemote.GetBuildParameters(); // Run command var inputHashes = new DictionaryStore <InputVersionKey, ObjectId>(VirtualFileSystem.OpenStream("/data/db/InputHashes", VirtualFileMode.OpenOrCreate, VirtualFileAccess.ReadWrite, VirtualFileShare.ReadWrite)); var builderContext = new BuilderContext(buildPath, inputHashes, parameters, 0, null); var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger); command.PreCommand(commandContext); status = await command.DoCommand(commandContext); command.PostCommand(commandContext, status); // Returns result to master builder processBuilderRemote.RegisterResult(commandContext.ResultEntry); }); while (true) { scheduler.Run(); // Exit loop if no more micro threads lock (scheduler.MicroThreads) { if (!scheduler.MicroThreads.Any()) { break; } } Thread.Sleep(0); } // Rethrow any exception that happened in microthread if (microthread.Exception != null) { options.Logger.Fatal(microthread.Exception.ToString()); return(BuildResultCode.BuildError); } if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful) { return(BuildResultCode.Successful); } return(BuildResultCode.BuildError); } finally { // Close WCF channel // ReSharper disable SuspiciousTypeConversion.Global ((IClientChannel)processBuilderRemote).Close(); // ReSharper restore SuspiciousTypeConversion.Global } }
private void AddMicroThread(MicroThread microThread) { Dispatcher.BeginInvoke((Action)delegate { microThreads.Add(new MicroThreadViewModel(microThread)); }, null); }