/// <summary> /// Load a WorkspaceModel from json. If the WorkspaceModel is a HomeWorkspaceModel /// it will be set as the current workspace. /// </summary> /// <param name="json"></param> public static WorkspaceModel LoadWorkspaceFromJson(string json, LibraryServices libraryServices, EngineController engineController, DynamoScheduler scheduler, NodeFactory factory, bool isTestMode, bool verboseLogging, CustomNodeManager manager) { var settings = new JsonSerializerSettings { Error = (sender, args) => { args.ErrorContext.Handled = true; Console.WriteLine(args.ErrorContext.Error); }, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, TypeNameHandling = TypeNameHandling.Auto, Formatting = Formatting.Indented, Converters = new List<JsonConverter>{ new ConnectorConverter(), new AnnotationConverter(), new WorkspaceConverter(engineController, scheduler, factory, isTestMode, verboseLogging), new NodeModelConverter(manager, libraryServices), }, ReferenceResolverProvider = () => { return new IdReferenceResolver(); } }; var result = ReplaceTypeDeclarations(json, true); var ws = JsonConvert.DeserializeObject<WorkspaceModel>(result, settings); return ws; }
public void TestTaskStateChangedEventHandling() { var observer = new TaskEventObserver(); var schedulerThread = new SampleSchedulerThread(); var scheduler = new DynamoScheduler(schedulerThread, TaskProcessMode.Asynchronous); scheduler.TaskStateChanged += observer.OnTaskStateChanged; // Start scheduling a bunch of tasks. var asyncTasks = new AsyncTask[] { new ErrorProneAsyncTask(scheduler, 7), new InconsequentialAsyncTask(scheduler, 100), new PrioritizedAsyncTask(scheduler, 1), new PrioritizedAsyncTask(scheduler, 5), new ErrorProneAsyncTask(scheduler, 3), new InconsequentialAsyncTask(scheduler, 500), new InconsequentialAsyncTask(scheduler, 300), new PrioritizedAsyncTask(scheduler, 3), new ErrorProneAsyncTask(scheduler, 5), }; foreach (SampleAsyncTask asyncTask in asyncTasks) scheduler.ScheduleForExecution(asyncTask); schedulerThread.GetSchedulerToProcessTasks(); // Drops all InconsequentialAsyncTask and leave behind one. // Kept all PrioritizedAsyncTask instances and sorted them. var expected = new List<string> { // Scheduling notifications... "Scheduled: ErrorProneAsyncTask: 7", "Scheduled: InconsequentialAsyncTask: 100", "Scheduled: PrioritizedAsyncTask: 1", "Scheduled: PrioritizedAsyncTask: 5", "Scheduled: ErrorProneAsyncTask: 3", "Scheduled: InconsequentialAsyncTask: 500", "Scheduled: InconsequentialAsyncTask: 300", "Scheduled: PrioritizedAsyncTask: 3", "Scheduled: ErrorProneAsyncTask: 5", // Task discarded notifications... "Discarded: InconsequentialAsyncTask: 100", "Discarded: InconsequentialAsyncTask: 300", // Execution of remaining tasks... "ExecutionStarting: ErrorProneAsyncTask: 7", "ExecutionFailed: ErrorProneAsyncTask: 7", "CompletionHandled: ErrorProneAsyncTask: 7", "ExecutionStarting: PrioritizedAsyncTask: 1", "ExecutionCompleted: PrioritizedAsyncTask: 1", "CompletionHandled: PrioritizedAsyncTask: 1", "ExecutionStarting: PrioritizedAsyncTask: 5", "ExecutionCompleted: PrioritizedAsyncTask: 5", "CompletionHandled: PrioritizedAsyncTask: 5", "ExecutionStarting: ErrorProneAsyncTask: 3", "ExecutionFailed: ErrorProneAsyncTask: 3", "CompletionHandled: ErrorProneAsyncTask: 3", "ExecutionStarting: PrioritizedAsyncTask: 3", "ExecutionCompleted: PrioritizedAsyncTask: 3", "CompletionHandled: PrioritizedAsyncTask: 3", "ExecutionStarting: ErrorProneAsyncTask: 5", "ExecutionFailed: ErrorProneAsyncTask: 5", "CompletionHandled: ErrorProneAsyncTask: 5", // Execution of InconsequentialAsyncTask last... "ExecutionStarting: InconsequentialAsyncTask: 500", "ExecutionCompleted: InconsequentialAsyncTask: 500", "CompletionHandled: InconsequentialAsyncTask: 500" }; Assert.AreEqual(expected.Count, observer.Results.Count()); int index = 0; foreach (var actual in observer.Results) { Assert.AreEqual(expected[index++], actual); } }
public void TestTaskQueuePreProcessing06() { var schedulerThread = new SampleSchedulerThread(); var scheduler = new DynamoScheduler(schedulerThread, TaskProcessMode.Asynchronous); schedulerThread.GetSchedulerToProcessTasks(); Assert.Pass("Scheduler thread successfully exits"); }
internal SampleAsyncTask(DynamoScheduler scheduler) : base(scheduler) { }
public void TestTaskQueuePreProcessing05() { var schedulerThread = new SampleSchedulerThread(); var scheduler = new DynamoScheduler(schedulerThread, TaskProcessMode.Asynchronous); // Start scheduling a bunch of tasks. var asyncTasks = new AsyncTask[] { new PrioritizedAsyncTask(scheduler, 1), new InconsequentialAsyncTask(scheduler, 100), }; var results = new List<string>(); foreach (SampleAsyncTask asyncTask in asyncTasks) { asyncTask.InitializeWithResultList(results); scheduler.ScheduleForExecution(asyncTask); } schedulerThread.GetSchedulerToProcessTasks(); // Drops all InconsequentialAsyncTask and leave behind one. // Kept all PrioritizedAsyncTask instances and sorted them. Assert.AreEqual(2, results.Count); Assert.AreEqual("PrioritizedAsyncTask: 1", results[0]); Assert.AreEqual("InconsequentialAsyncTask: 100", results[1]); }
public WorkspaceConverter(EngineController engine, DynamoScheduler scheduler, NodeFactory factory, bool isTestMode, bool verboseLogging) { this.scheduler = scheduler; this.engine = engine; this.factory = factory; this.isTestMode = isTestMode; this.verboseLogging = verboseLogging; }
/// <summary> /// Default constructor for DynamoModel /// </summary> /// <param name="config">Start configuration</param> protected DynamoModel(IStartConfiguration config) { ClipBoard = new ObservableCollection<ModelBase>(); pathManager = new PathManager(new PathManagerParams { CorePath = config.DynamoCorePath, HostPath = config.DynamoHostPath, PathResolver = config.PathResolver }); // Ensure we have all directories in place. var exceptions = new List<Exception>(); pathManager.EnsureDirectoryExistence(exceptions); Context = config.Context; IsTestMode = config.StartInTestMode; var config2 = config as IStartConfiguration2; IsHeadless = (config2 != null) ? config2.IsHeadless : false; DebugSettings = new DebugSettings(); Logger = new DynamoLogger(DebugSettings, pathManager.LogDirectory); foreach (var exception in exceptions) { Logger.Log(exception); // Log all exceptions. } MigrationManager = new MigrationManager(DisplayFutureFileMessage, DisplayObsoleteFileMessage); MigrationManager.MessageLogged += LogMessage; MigrationManager.MigrationTargets.Add(typeof(WorkspaceMigrations)); var thread = config.SchedulerThread ?? new DynamoSchedulerThread(); Scheduler = new DynamoScheduler(thread, config.ProcessMode); Scheduler.TaskStateChanged += OnAsyncTaskStateChanged; geometryFactoryPath = config.GeometryFactoryPath; IPreferences preferences = CreateOrLoadPreferences(config.Preferences); var settings = preferences as PreferenceSettings; if (settings != null) { PreferenceSettings = settings; PreferenceSettings.PropertyChanged += PreferenceSettings_PropertyChanged; } InitializeInstrumentationLogger(); if (!IsTestMode && PreferenceSettings.IsFirstRun) { DynamoMigratorBase migrator = null; try { var dynamoLookup = config.UpdateManager != null && config.UpdateManager.Configuration != null ? config.UpdateManager.Configuration.DynamoLookUp : null; migrator = DynamoMigratorBase.MigrateBetweenDynamoVersions(pathManager, dynamoLookup); } catch (Exception e) { Logger.Log(e.Message); } if (migrator != null) { var isFirstRun = PreferenceSettings.IsFirstRun; PreferenceSettings = migrator.PreferenceSettings; // Preserve the preference settings for IsFirstRun as this needs to be set // only by UsageReportingManager PreferenceSettings.IsFirstRun = isFirstRun; } } InitializePreferences(PreferenceSettings); // At this point, pathManager.PackageDirectories only has 1 element which is the directory // in AppData. If list of PackageFolders is empty, add the folder in AppData to the list since there // is no additional location specified. Otherwise, update pathManager.PackageDirectories to include // PackageFolders if (PreferenceSettings.CustomPackageFolders.Count == 0) PreferenceSettings.CustomPackageFolders = new List<string> {pathManager.UserDataDirectory}; //Make sure that the default package folder is added in the list if custom packages folder. var userDataFolder = pathManager.GetUserDataFolder(); //Get the default user data path if (Directory.Exists(userDataFolder) && !PreferenceSettings.CustomPackageFolders.Contains(userDataFolder)) { PreferenceSettings.CustomPackageFolders.Add(userDataFolder); } pathManager.Preferences = PreferenceSettings; SearchModel = new NodeSearchModel(); SearchModel.ItemProduced += node => ExecuteCommand(new CreateNodeCommand(node, 0, 0, true, true)); NodeFactory = new NodeFactory(); NodeFactory.MessageLogged += LogMessage; CustomNodeManager = new CustomNodeManager(NodeFactory, MigrationManager); InitializeCustomNodeManager(); extensionManager = new ExtensionManager(); extensionManager.MessageLogged += LogMessage; var extensions = config.Extensions ?? LoadExtensions(); Loader = new NodeModelAssemblyLoader(); Loader.MessageLogged += LogMessage; // Create a core which is used for parsing code and loading libraries var libraryCore = new ProtoCore.Core(new Options()); libraryCore.Compilers.Add(Language.Associative, new Compiler(libraryCore)); libraryCore.Compilers.Add(Language.Imperative, new ProtoImperative.Compiler(libraryCore)); libraryCore.ParsingMode = ParseMode.AllowNonAssignment; LibraryServices = new LibraryServices(libraryCore, pathManager, PreferenceSettings); LibraryServices.MessageLogged += LogMessage; LibraryServices.LibraryLoaded += LibraryLoaded; ResetEngineInternal(); AddHomeWorkspace(); AuthenticationManager = new AuthenticationManager(config.AuthProvider); UpdateManager = config.UpdateManager ?? new DefaultUpdateManager(null); // config.UpdateManager has to be cast to IHostUpdateManager in order to extract the HostVersion and HostName // see IHostUpdateManager summary for more details var hostUpdateManager = config.UpdateManager as IHostUpdateManager; if (hostUpdateManager != null) { HostName = hostUpdateManager.HostName; HostVersion = hostUpdateManager.HostVersion == null ? null : hostUpdateManager.HostVersion.ToString(); } else { HostName = string.Empty; HostVersion = null; } UpdateManager.Log += UpdateManager_Log; if (!IsTestMode && !IsHeadless) { DefaultUpdateManager.CheckForProductUpdate(UpdateManager); } Logger.Log(string.Format("Dynamo -- Build {0}", Assembly.GetExecutingAssembly().GetName().Version)); InitializeNodeLibrary(PreferenceSettings); if (extensions.Any()) { var startupParams = new StartupParams(config.AuthProvider, pathManager, new ExtensionLibraryLoader(this), CustomNodeManager, GetType().Assembly.GetName().Version, PreferenceSettings); foreach (var ext in extensions) { var logSource = ext as ILogSource; if (logSource != null) logSource.MessageLogged += LogMessage; try { ext.Startup(startupParams); } catch (Exception ex) { Logger.Log(ex.Message); } ExtensionManager.Add(ext); } } LogWarningMessageEvents.LogWarningMessage += LogWarningMessage; StartBackupFilesTimer(); TraceReconciliationProcessor = this; foreach (var ext in ExtensionManager.Extensions) { try { ext.Ready(new ReadyParams(this)); } catch (Exception ex) { Logger.Log(ex.Message); } } }
public HomeWorkspaceModel( EngineController engine, DynamoScheduler scheduler, NodeFactory factory, IEnumerable<KeyValuePair<Guid, List<string>>> traceData, IEnumerable<NodeModel> nodes, IEnumerable<NoteModel> notes, IEnumerable<AnnotationModel> annotations, IEnumerable<PresetModel> presets, ElementResolver resolver, WorkspaceInfo info, bool verboseLogging, bool isTestMode) : base(nodes, notes,annotations, info, factory,presets, resolver) { EvaluationCount = 0; // This protects the user from a file that might have crashed during // its last run. As a side effect, this also causes all files set to // run auto but lacking the HasRunWithoutCrash flag to run manually. if (info.RunType == RunType.Automatic && !info.HasRunWithoutCrash) { info.RunType = RunType.Manual; } RunSettings = new RunSettings(info.RunType, info.RunPeriod); PreloadedTraceData = traceData; this.scheduler = scheduler; this.verboseLogging = verboseLogging; IsTestMode = isTestMode; EngineController = engine; // The first time the preloaded trace data is set, we cache // the data as historical. This will be used after the initial // run of this workspace, when the PreloadedTraceData has been // nulled, to check for node deletions and reconcile the trace data. // We do a deep copy of this data because the PreloadedTraceData is // later set to null before the graph update. var copiedData = new List<KeyValuePair<Guid, List<string>>>(); foreach (var kvp in PreloadedTraceData) { var strings = kvp.Value.Select(string.Copy).ToList(); copiedData.Add(new KeyValuePair<Guid, List<string>>(kvp.Key, strings)); } historicalTraceData = copiedData; }
internal void OnTaskStateChanged( DynamoScheduler scheduler, TaskStateChangedEventArgs e) { AddToResultList(e.Task.ToString(), e.CurrentState); }
internal void GrabTimeStamp(DynamoScheduler scheduler) { // Get the time-stamp value from the scheduler. this.TimeStampValue = scheduler.NextTimeStamp; this.doneEvent.Set(); // Done with grabbing. }
internal ErrorProneAsyncTask(DynamoScheduler scheduler, int value) : base(scheduler) { Value = value; }
internal InconsequentialAsyncTask(DynamoScheduler scheduler, int punch) : base(scheduler) { Punch = punch; }
public void TestUpdateGraphyAsyncTaskMerge() { // Verify a UpdateGraphAysncTask can't be merged with the other one // if they modifiy different nodes. OpenModel(TestDirectory + @"\core\scheduler\simple.dyn"); var cbn = CurrentDynamoModel.CurrentWorkspace.Nodes.OfType<CodeBlockNodeModel>().FirstOrDefault(); var funcNode = CurrentDynamoModel.CurrentWorkspace.Nodes.OfType<DSFunction>().FirstOrDefault(); // Keep code block node be silent so that the graph won't be // executed automatically cbn.RaisesModificationEvents = false; var elementResolver = CurrentDynamoModel.CurrentWorkspace.ElementResolver; cbn.SetCodeContent("-22", elementResolver); // Invalid numeric value. cbn.MarkNodeAsModified(); // Get a UpdateGrapyAsyncTask for the modification of cbn var scheduler = new DynamoScheduler(new SampleSchedulerThread(), TaskProcessMode.Synchronous); UpdateGraphAsyncTask task1 = new UpdateGraphAsyncTask(scheduler, false); task1.Initialize(CurrentDynamoModel.EngineController, CurrentDynamoModel.CurrentWorkspace); // Get a UpdateGraphAsyncTask for the modification of Math.Sin() funcNode.MarkNodeAsModified(); UpdateGraphAsyncTask task2 = new UpdateGraphAsyncTask(scheduler, false); task2.Initialize(CurrentDynamoModel.EngineController, CurrentDynamoModel.CurrentWorkspace); // And both async tasks should be kept. var mergeResult = task1.CanMergeWith(task2); Assert.AreEqual(AsyncTask.TaskMergeInstruction.KeepBoth, mergeResult); mergeResult = task2.CanMergeWith(task1); Assert.AreEqual(AsyncTask.TaskMergeInstruction.KeepBoth, mergeResult); scheduler.Shutdown(); }
internal PrioritizedAsyncTask(DynamoScheduler scheduler, int priority) : base(scheduler) { CurrPriority = priority; // Assign task priority. }
/// <summary> /// This event handler is invoked when DynamoScheduler changes the state /// of an AsyncTask object. See TaskStateChangedEventArgs.State for more /// details of these state changes. /// </summary> /// <param name="sender">The scheduler which raised the event.</param> /// <param name="e">Task state changed event argument.</param> /// private void OnAsyncTaskStateChanged(DynamoScheduler sender, TaskStateChangedEventArgs e) { switch (e.CurrentState) { case TaskStateChangedEventArgs.State.ExecutionStarting: if (e.Task is UpdateGraphAsyncTask) ExecutionEvents.OnGraphPreExecution(); break; case TaskStateChangedEventArgs.State.ExecutionCompleted: if (e.Task is UpdateGraphAsyncTask) { // Record execution time for update graph task. long start = e.Task.ExecutionStartTime.TickCount; long end = e.Task.ExecutionEndTime.TickCount; var executionTimeSpan = new TimeSpan(end - start); InstrumentationLogger.LogAnonymousTimedEvent( "Perf", e.Task.GetType().Name, executionTimeSpan); Debug.WriteLine(String.Format(Resources.EvaluationCompleted, executionTimeSpan)); ExecutionEvents.OnGraphPostExecution(); } break; } }
public HomeWorkspaceModel(EngineController engine, DynamoScheduler scheduler, NodeFactory factory, bool verboseLogging, bool isTestMode, string fileName="") : this( engine, scheduler, factory, Enumerable.Empty<KeyValuePair<Guid, List<string>>>(), Enumerable.Empty<NodeModel>(), Enumerable.Empty<NoteModel>(), Enumerable.Empty<AnnotationModel>(), Enumerable.Empty<PresetModel>(), new ElementResolver(), new WorkspaceInfo(){FileName = fileName, Name = "Home"}, verboseLogging, isTestMode) { }
public void TimeStampGenerator00() { var scheduler = new DynamoScheduler(new SampleSchedulerThread(), TaskProcessMode.Synchronous); Assert.AreEqual(1024, scheduler.NextTimeStamp.Identifier); Assert.AreEqual(1025, scheduler.NextTimeStamp.Identifier); Assert.AreEqual(1026, scheduler.NextTimeStamp.Identifier); }
public void TimeStampGenerator01() { const int EventCount = 16; var events = new ManualResetEvent[EventCount]; var grabbers = new TimeStampGrabber[EventCount]; // Initialize events and time stamp grabbers. for (int index = 0; index < EventCount; ++index) { events[index] = new ManualResetEvent(false); grabbers[index] = new TimeStampGrabber(events[index]); } // Start all time-stamp grabbers "at one go". var scheduler = new DynamoScheduler(new SampleSchedulerThread(), TaskProcessMode.Synchronous); Parallel.For(0, EventCount, ((index) => { grabbers[index].GrabTimeStamp(scheduler); })); WaitHandle.WaitAll(events); var values = new List<TimeStamp>(); for (int index = 0; index < EventCount; ++index) values.Add(grabbers[index].TimeStampValue); // Ensure we get a list of time stamps, and that these numbers are // all unique (i.e. the distinct set of numbers returned should have // the same count as the original list). // Assert.AreEqual(EventCount, values.Count); var distinct = values.Distinct(); Assert.AreEqual(values.Count, distinct.Count()); }
public void TestSchedulerCreationDestruction() { var schedulerThread = new SampleSchedulerThread(); Assert.IsFalse(schedulerThread.Initialized); Assert.IsFalse(schedulerThread.Destroyed); var scheduler = new DynamoScheduler(schedulerThread, TaskProcessMode.Asynchronous); Assert.IsTrue(schedulerThread.Initialized); Assert.IsFalse(schedulerThread.Destroyed); scheduler.Shutdown(); Assert.IsTrue(schedulerThread.Initialized); Assert.IsTrue(schedulerThread.Destroyed); }
/// <summary> /// This event handler is invoked when DynamoScheduler changes the state /// of an AsyncTask object. See TaskStateChangedEventArgs.State for more /// details of these state changes. /// </summary> /// <param name="sender">The scheduler which raised the event.</param> /// <param name="e">Task state changed event argument.</param> /// private void OnAsyncTaskStateChanged(DynamoScheduler sender, TaskStateChangedEventArgs e) { var updateTask = e.Task as UpdateGraphAsyncTask; switch (e.CurrentState) { case TaskStateChangedEventArgs.State.ExecutionStarting: if (updateTask != null) ExecutionEvents.OnGraphPreExecution(new ExecutionSession(updateTask, this, geometryFactoryPath)); break; case TaskStateChangedEventArgs.State.ExecutionCompleted: if (updateTask != null) { // Record execution time for update graph task. long start = e.Task.ExecutionStartTime.TickCount; long end = e.Task.ExecutionEndTime.TickCount; var executionTimeSpan = new TimeSpan(end - start); if (Logging.Analytics.ReportingAnalytics) { var modifiedNodes = ""; if (updateTask.ModifiedNodes != null && updateTask.ModifiedNodes.Any()) { modifiedNodes = updateTask.ModifiedNodes .Select(n => n.GetOriginalName()) .Aggregate((x, y) => string.Format("{0}, {1}", x, y)); } Dynamo.Logging.Analytics.TrackTimedEvent( Categories.Performance, e.Task.GetType().Name, executionTimeSpan, modifiedNodes); } Debug.WriteLine(String.Format(Resources.EvaluationCompleted, executionTimeSpan)); ExecutionEvents.OnGraphPostExecution(new ExecutionSession(updateTask, this, geometryFactoryPath)); } break; } }
public HomeWorkspaceModel(Guid guid, EngineController engine, DynamoScheduler scheduler, NodeFactory factory, IEnumerable<KeyValuePair<Guid, List<CallSite.RawTraceData>>> traceData, IEnumerable<NodeModel> nodes, IEnumerable<NoteModel> notes, IEnumerable<AnnotationModel> annotations, IEnumerable<PresetModel> presets, ElementResolver resolver, WorkspaceInfo info, bool verboseLogging, bool isTestMode):this(engine, scheduler, factory, traceData, nodes, notes, annotations, presets, resolver, info, verboseLogging, isTestMode) { Guid = guid; }