Exemple #1
0
        /// <summary>
        /// Adds the node.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="metadata">The metadata.</param>
        public override void AddNode(String id, Metadata metadata, LoggerNameRoot loggerNameRoot)
        {
            // adds a node to the graph
            RunnableNode node = m_nodesFactory.CreateNode(id, metadata, loggerNameRoot, Library, ComponentsAppDomain, TerminateExperimentExecutionResetEvent);

            if (node is RunnableStartNode)
            {
                //allow set only once
                if (m_startNode != null)
                {
                    throw new TraceLab.Core.Exceptions.InconsistentTemplateException("Template cannot have two start nodes defined.");
                }
                m_startNode = node;
            }
            if (node is RunnableEndNode)
            {
                //allow set only once
                if (m_endNode != null)
                {
                    throw new TraceLab.Core.Exceptions.InconsistentTemplateException("Template cannot have two end nodes defined.");
                }
                m_endNode = node;
            }
            m_nodes.Add(node);
        }
Exemple #2
0
        /// <summary>
        /// Compiles the decision.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="experiment">The experiment.</param>
        /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        private static void CompileDecisionInternal(ExperimentNode node, IExperiment experiment, List <string> workspaceTypesDirectories,
                                                    LoggerNameRoot loggerNameRoot, Dictionary <string, string> successorNodeLabelIdLookup)
        {
            InputMappings availableInputMappingsPerNode = new InputMappings(experiment);

            Dictionary <string, string> predeccessorsOutputsNameTypeLookup = PreparePredeccessorsOutputsNameTypeLookup(node, availableInputMappingsPerNode);

            IDecision decisionMetadata = (IDecision)node.Data.Metadata;

            try
            {
                if (decisionMetadata != null)
                {
                    node.ClearError();

                    BuildSourceAndCompileDecisionModule(decisionMetadata, successorNodeLabelIdLookup, predeccessorsOutputsNameTypeLookup, workspaceTypesDirectories, loggerNameRoot);

                    decisionMetadata.CompilationStatus = TraceLab.Core.Components.CompilationStatus.Successful;
                }
            }
            catch (ArgumentException ex)
            {
                decisionMetadata.CompilationStatus = TraceLab.Core.Components.CompilationStatus.Failed;
                node.SetError(ex.Message);
            }
        }
        /// <summary>
        /// Handles the event of Check Code Button Click.
        /// It compiles decision code.
        /// </summary>
        /// <param name="sender">Sender.</param>
        /// <param name="e">E.</param>
        protected void CheckCode(object sender, EventArgs e)
        {
            fillLoadComboBox();

            List <string>  workspaceTypeDirectories = m_applicationContext.Application.WorkspaceViewModel.WorkspaceTypeDirectories;
            Experiment     experiment     = m_applicationContext.Application.Experiment;
            LoggerNameRoot loggerNameRoot = new LoggerNameRoot(experiment.ExperimentInfo.Id);

            //compile decision - the result is set in metadata Compilation Status, and eventual message in Error
            TraceLab.Core.Decisions.DecisionCompilationRunner.CompileDecision(m_loopControl.ExperimentNode,
                                                                              experiment,
                                                                              workspaceTypeDirectories,
                                                                              loggerNameRoot);

            //retrieve compilation status from metadata
            if (m_metadata.CompilationStatus == CompilationStatus.Successful)
            {
                this.errorTextView1.ShowInfoMessage("Compilation successful!");
            }
            //otherwise error displays on ErrorChanged event - see HandleErrorChanged method

            if (this.errorTextView1.Visible)
            {
                this.GdkWindow.Resize(381, 375);
            }
        }
Exemple #4
0
        /// <summary>
        /// Creates the Runnable node with a specific id based on the given metadata.
        /// Uses Composite Component Metadata config values to override Components config values in subgraph.
        /// </summary>
        /// <param name="id">The id of the node.</param>
        /// <param name="metadata">The component metadata.</param>
        /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
        /// <param name="library">The library of components.</param>
        /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment;
        /// Needed for the composite components sublevel experiments, so that they hold the referance to the same termination event as top level experiment</param>
        /// <returns>
        /// Created node
        /// </returns>
        public override RunnableNode CreateNode(String id, Metadata metadata, LoggerNameRoot loggerNameRoot, ComponentsLibrary library,
                                                AppDomain componentsAppDomain, System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
        {
            RunnableNode retNode;

            ComponentMetadata          originalComponentMetadata  = metadata as ComponentMetadata;
            CompositeComponentMetadata compositeComponentMetadata = metadata as CompositeComponentMetadata;

            if (originalComponentMetadata != null)
            {
                ComponentMetadata overrideComponentMetadata = (ComponentMetadata)originalComponentMetadata.Clone();
                OverrideConfigValues(id, overrideComponentMetadata);
                retNode = base.CreateNode(id, overrideComponentMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (compositeComponentMetadata != null)
            {
                OverrideConfigValues(id, compositeComponentMetadata);
                retNode = base.CreateCompositeComponentNode(id, compositeComponentMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else
            {
                retNode = base.CreateNode(id, metadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }

            return(retNode);
        }
Exemple #5
0
        /// <summary>
        /// Creates the Runnable node with a specific id based on the given metadata.
        /// </summary>
        /// <param name="nodeId">The node id.</param>
        /// <param name="metadata">The component metadata.</param>
        /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
        /// <param name="library">The library of components.</param>
        /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment;
        /// Needed for the composite components sublevel experiments, so that they hold the referance to the same termination event as top level experiment.</param>
        /// <returns>
        /// Created node
        /// </returns>
        public virtual RunnableNode CreateNode(String nodeId, Metadata metadata, LoggerNameRoot loggerNameRoot,
                                               ComponentsLibrary library, AppDomain componentsAppDomain, System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
        {
            RunnableNode retNode;

            ComponentMetadata          componentMetadata          = metadata as ComponentMetadata;
            DecisionMetadata           decisionMetadata           = metadata as DecisionMetadata;
            StartNodeMetadata          startNodeMetadata          = metadata as StartNodeMetadata;
            EndNodeMetadata            endNodeMetadata            = metadata as EndNodeMetadata;
            ScopeBaseMetadata          scopeMetadata              = metadata as ScopeBaseMetadata;
            LoopScopeMetadata          loopMetadata               = metadata as LoopScopeMetadata;
            CompositeComponentMetadata compositeComponentMetadata = metadata as CompositeComponentMetadata;
            ExitDecisionMetadata       exitDecisionMetadata       = metadata as ExitDecisionMetadata;

            if (componentMetadata != null)
            {
                TraceLabSDK.ComponentLogger logger = TraceLab.Core.Components.LoggerFactory.CreateLogger(loggerNameRoot, nodeId, componentMetadata);
                IComponent component = library.LoadComponent(componentMetadata, Workspace, logger, componentsAppDomain);
                retNode = new RunnableComponentNode(nodeId, componentMetadata.Label, component, logger, library, componentMetadata.WaitsForAllPredecessors);
            }
            else if (decisionMetadata != null)
            {
                IDecisionModule decisionModule = DecisionModuleFactory.LoadDecisionModule(decisionMetadata, Workspace, componentsAppDomain);
                retNode = new RunnableDecisionNode(nodeId, decisionMetadata.Label, decisionModule, library, decisionMetadata.WaitsForAllPredecessors);
            }
            else if (startNodeMetadata != null)
            {
                retNode = new RunnableStartNode(nodeId);
            }
            else if (endNodeMetadata != null)
            {
                retNode = new RunnableEndNode(nodeId, endNodeMetadata.WaitsForAllPredecessors);
            }
            else if (loopMetadata != null)
            {
                retNode = CreateLoopNode(nodeId, loopMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (scopeMetadata != null)
            {
                retNode = CreateScopeCompositeComponentNode(nodeId, scopeMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (compositeComponentMetadata != null)
            {
                retNode = CreateCompositeComponentNode(nodeId, compositeComponentMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (exitDecisionMetadata != null)
            {
                retNode = new RunnablePrimitiveNode(nodeId, exitDecisionMetadata.WaitsForAllPredecessors);
            }
            else
            {
                throw new Exceptions.InconsistentTemplateException("Could not identify node type.");
            }

            return(retNode);
        }
Exemple #6
0
        /// <summary>
        /// Adapts the specified experiment into runnable experiment.
        /// Adapt method validates given experiment and builds runnable experiment which is going to be executed by the experiment runner.
        /// During adapation the experiment is validated.
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// There are several errors that can be detected.
        /// There are nodes connected to start, but not to graph end.
        /// Loops without decisions nodes.
        /// Input mappings are incorrect.
        /// Failed component load or instantiation, especially in case of incorrect configuration values.
        /// </summary>
        /// <param name="experiment">The experiment which is going to be adapted into RunnableExperiment..</param>
        /// <param name="nodesFactory">The nodes factory, by which all nodes in runnable experiment are created..</param>
        /// <param name="library">The library of components.</param>
        /// <param name="workspaceTypeDirectories">The workspace type directories.</param>
        /// <returns>
        /// Runnable experiment that experiment is going to execute, pruned from nodes that are not connected to main flow beginning at Start node.
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// </returns>
        public static RunnableExperimentBase Adapt(IExperiment experiment, IRunnableNodeFactory nodesFactory, Components.ComponentsLibrary library, List <string> workspaceTypeDirectories)
        {
            LoggerNameRoot loggerNameRoot = new LoggerNameRoot(experiment.ExperimentInfo.Id);

            // Create the new domain for the runnable experiment with whatever current security evidence we're running with.
            // The components app domain is the app domain which components assemblies are going to be loaded into.

            var       helper = new TraceLab.Core.Components.LibraryHelper(workspaceTypeDirectories);
            AppDomain componentsAppDomain = helper.CreateDomain(experiment.ExperimentInfo.Id);

            return(Adapt(experiment, loggerNameRoot, nodesFactory, library, workspaceTypeDirectories, componentsAppDomain, new System.Threading.ManualResetEvent(false), true));
        }
Exemple #7
0
        /// <summary>
        /// Adapts the specified experiment into runnable experiment.
        /// Adapt method validates given experiment and builds runnable experiment which is going to be executed by the experiment runner.
        /// During adapation the experiment is validated.
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// There are several errors that can be detected.
        /// There are nodes connected to start, but not to graph end.
        /// Loops without decisions nodes.
        /// Input mappings are incorrect.
        /// Failed component load or instantiation, especially in case of incorrect configuration values.
        /// </summary>
        /// <param name="experiment">The experiment which is going to be adapted into RunnableExperiment..</param>
        /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
        /// <param name="nodesFactory">The nodes factory, by which all nodes in runnable experiment are created..</param>
        /// <param name="library">The library of components.</param>
        /// <param name="workspaceTypeDirectories">The workspace type directories.</param>
        /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment</param>
        /// <returns>
        /// Runnable experiment that experiment is going to execute, pruned from nodes that are not connected to main flow beginning at Start node.
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// </returns>
        public static RunnableExperimentBase Adapt(IExperiment experiment, LoggerNameRoot loggerNameRoot, IRunnableNodeFactory nodesFactory,
                                                   Components.ComponentsLibrary library, List <string> workspaceTypeDirectories,
                                                   AppDomain componentsAppDomain, System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent, bool validateInputMapping)
        {
            RunnableExperimentBase runnableExperiment = new RunnableExperiment(nodesFactory, library, componentsAppDomain, terminateExperimentExecutionResetEvent);

            List <ExperimentNode>           vertices;
            List <ExperimentNodeConnection> edges;
            bool noErrors = ExperimentValidator.ValidateExperiment(experiment, out vertices, out edges, workspaceTypeDirectories, validateInputMapping, loggerNameRoot);

            if (noErrors)
            {
                foreach (ExperimentNode node in vertices)
                {
                    try
                    {
                        runnableExperiment.AddNode(node.ID, node.Data.Metadata, loggerNameRoot);
                    }
                    catch (TraceLab.Core.Exceptions.IncorrectSubTemplateException ex)
                    {
                        runnableExperiment.Clear();
                        noErrors = false;
                        NLog.LogManager.GetCurrentClassLogger().Error(ex.Message);
                        node.SetError(ex.Message);
                        break;
                    }
                    catch (Exception ex)
                    {
                        runnableExperiment.Clear();
                        noErrors = false;
                        string msg = "Unable to initialize component: " + ex.Message;
                        NLog.LogManager.GetCurrentClassLogger().Error(msg, ex);
                        node.SetError(msg);
                        break;
                    }
                }
            }

            if (noErrors)
            {
                foreach (ExperimentNodeConnection edge in edges)
                {
                    runnableExperiment.AddDirectedEdge(edge.Source.ID, edge.Target.ID);
                }
            }

            return(runnableExperiment);
        }
Exemple #8
0
        /// <summary>
        /// Constructs the sub experiment.
        /// </summary>
        /// <param name="compositeComponentMetadata">The composite component metadata.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="library">The library.</param>
        /// <param name="componentsAppDomain">The components app domain.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The terminate experiment execution reset event - must be the same as top level experiment termination event.</param>
        /// <param name="nodesFactoryOfSubGraph">The nodes factory of sub graph.</param>
        /// <returns></returns>
        private RunnableExperimentBase ConstructSubExperiment(CompositeComponentBaseMetadata compositeComponentMetadata, LoggerNameRoot loggerNameRoot,
                                                              ComponentsLibrary library, AppDomain componentsAppDomain,
                                                              System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent, IRunnableNodeFactory nodesFactoryOfSubGraph)
        {
            //add to experiment id the owner node id to make it unique
            LoggerNameRoot compositeComponentNodeLoggerNameRoot = loggerNameRoot.CreateLoggerNameRootForCompositeNode(compositeComponentMetadata);

            RunnableExperimentBase subExperiment = GraphAdapter.Adapt(compositeComponentMetadata.ComponentGraph, compositeComponentNodeLoggerNameRoot,
                                                                      nodesFactoryOfSubGraph, library, Workspace.TypeDirectories,
                                                                      componentsAppDomain, terminateExperimentExecutionResetEvent, false);

            if (subExperiment.IsEmpty)
            {
                throw new TraceLab.Core.Exceptions.IncorrectSubTemplateException("Unable to execute subexperiment due to errors.");
            }
            return(subExperiment);
        }
        /// <summary>
        /// Compiles the decision module func.
        /// </summary>
        /// <param name="param">The param.</param>
        private void CompileDecisionModuleFunc(object param)
        {
            var args = param as List <object>;

            if (args != null && args.Count == 2)
            {
                //validate args
                var node  = args[0] as ExperimentNode;
                var appVM = args[1] as ApplicationViewModelWrapper;

                if (node != null && appVM != null)
                {
                    List <string>  workspaceTypeDirectories = appVM.WorkspaceViewModel.WorkspaceTypeDirectories;
                    string         topExperimentId          = appVM.ExperimentViewModel.TopLevel.ExperimentInfo.Id;
                    LoggerNameRoot loggerNameRoot           = new LoggerNameRoot(topExperimentId);

                    TraceLab.Core.Decisions.DecisionCompilationRunner.CompileDecision(node, m_experiment, workspaceTypeDirectories, loggerNameRoot);
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Validates the entire experiment.
        /// It validates the structure of the experimental graph,
        /// validates all inputs and outputs,
        /// checks if all components are in the component library.
        /// </summary>
        /// <param name="experiment">The experiment.</param>
        /// <param name="vertices">The vertices, that has been parsed from the start node. Nodes that are not connected to the start are being skipped.</param>
        /// <param name="edges">The edges, that has been parsed from the start node.</param>
        /// <returns>
        /// true if there is no errors, false, if errors has been detected
        /// </returns>
        public static bool ValidateExperiment(IExperiment experiment, out List <ExperimentNode> vertices, out List <ExperimentNodeConnection> edges,
                                              List <string> workspaceTypesDirectories, bool validateInputMapping, LoggerNameRoot loggerNameRoot)
        {
            bool noErrors = GraphValidator.Validate(experiment, out vertices, out edges);

            if (noErrors)
            {
                var availableInputMappingsPerNode = new TraceLab.Core.Utilities.InputMappings(experiment);
                if (validateInputMapping)
                {
                    noErrors = InputMappingValidator.Validate(experiment, availableInputMappingsPerNode);
                }

                if (noErrors)
                {
                    //recompile all decisions
                    noErrors = TraceLab.Core.Decisions.DecisionCompilationRunner.CompileAllDecisionNodes(experiment, availableInputMappingsPerNode,
                                                                                                         workspaceTypesDirectories, loggerNameRoot);
                }
            }

            if (noErrors)
            {
                noErrors = ValidComponents(vertices);
            }

            return(noErrors);
        }
Exemple #11
0
        /// <summary>
        /// Creates the scope composite component node. It actually returns the composite component, but with different nested workspace wrapper.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="loopScopeMetadata">The scope metadata.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="library">The library.</param>
        /// <param name="componentsAppDomain">The components app domain.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The terminate experiment execution reset event.</param>
        /// <returns></returns>
        protected RunnableNode CreateLoopNode(string id, LoopScopeMetadata loopScopeMetadata, LoggerNameRoot loggerNameRoot,
                                              ComponentsLibrary library, AppDomain componentsAppDomain,
                                              System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
        {
            ScopeNestedWorkspaceWrapper workspaceWrapper = WorkspaceWrapperFactory.CreateCompositeComponentWorkspaceWrapper(loopScopeMetadata, Workspace, id, componentsAppDomain);

            //scope can standard runnable factory, unlike the composite component
            IRunnableNodeFactory nodesFactory = new RunnableNodeFactory(workspaceWrapper);

            RunnableExperimentBase subExperiment = ConstructSubExperiment(loopScopeMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent, nodesFactory);

            ILoopDecisionModule decisionModule = DecisionModuleFactory.LoadDecisionModule(loopScopeMetadata, Workspace, componentsAppDomain);

            return(new RunnableLoopNode(id, decisionModule, loopScopeMetadata, subExperiment, workspaceWrapper, library, loopScopeMetadata.WaitsForAllPredecessors));
        }
Exemple #12
0
        /// <summary>
        /// Creates the composite component node.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="compositeComponentMetadata">The composite component metadata.</param>
        /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
        /// <param name="library">The library of components.</param>
        /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment; The sublevel experiments hold the referance to the same termination event as top level experiment.</param>
        /// <returns>
        /// Created composite component node
        /// </returns>
        protected RunnableNode CreateCompositeComponentNode(string id, CompositeComponentMetadata compositeComponentMetadata, LoggerNameRoot loggerNameRoot,
                                                            ComponentsLibrary library, AppDomain componentsAppDomain,
                                                            System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
        {
            NestedWorkspaceWrapper workspaceWrapper       = WorkspaceWrapperFactory.CreateCompositeComponentWorkspaceWrapper(compositeComponentMetadata, Workspace, id, componentsAppDomain);
            NodesFactoryOfSubGraph nodesFactoryOfSubGraph = new NodesFactoryOfSubGraph(compositeComponentMetadata, workspaceWrapper);

            RunnableExperimentBase subExperiment = ConstructSubExperiment(compositeComponentMetadata, loggerNameRoot, library,
                                                                          componentsAppDomain, terminateExperimentExecutionResetEvent, nodesFactoryOfSubGraph);

            return(new RunnableCompositeComponentNode(id, compositeComponentMetadata, subExperiment, workspaceWrapper, library, compositeComponentMetadata.WaitsForAllPredecessors));
        }
Exemple #13
0
        /// <summary>
        /// Compiles all decision nodes code and loops code in the given experiment
        /// </summary>
        /// <param name="experiment">The experiment.</param>
        /// <param name="availableInputMappingsPerNode">The available input mappings per node.</param>
        /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <returns>
        /// true if there were no errors, otherwise false
        /// </returns>
        public static bool CompileAllDecisionNodes(IExperiment experiment, InputMappings availableInputMappingsPerNode,
                                                   List <string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
        {
            bool noErrors = true;

            foreach (ExperimentNode node in experiment.Vertices)
            {
                IDecision decisionMetadata = node.Data.Metadata as IDecision;
                if (decisionMetadata != null)
                {
                    try
                    {
                        //build successor nodes label id lookup
                        Dictionary <string, string> successorNodeLabelIdLookup         = PrepareSuccessorNodesLabelIdLookup(node, experiment);
                        Dictionary <string, string> predeccessorsOutputsNameTypeLookup = PreparePredeccessorsOutputsNameTypeLookup(node, availableInputMappingsPerNode);

                        node.ClearError();

                        BuildSourceAndCompileDecisionModule(decisionMetadata, successorNodeLabelIdLookup,
                                                            predeccessorsOutputsNameTypeLookup, workspaceTypesDirectories, loggerNameRoot);
                    }
                    catch (ArgumentException ex)
                    {
                        noErrors = false;
                        node.SetError(ex.Message);
                    }
                }
            }

            return(noErrors);
        }
Exemple #14
0
        /// <summary>
        /// Compiles the code of the single decision node or loop scope node. It handles DecisionNode and LoopScopeNode slightly differently.
        /// Method.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="experiment">The experiment.</param>
        /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        public static void CompileDecision(ExperimentNode node, IExperiment experiment, List <string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
        {
            ExperimentDecisionNode decisionNode = node as ExperimentDecisionNode;

            if (decisionNode != null)
            {
                Dictionary <string, string> successorNodeLabelIdLookup = PrepareSuccessorNodesLabelIdLookup(node, experiment);
                CompileDecisionInternal(decisionNode, experiment, workspaceTypesDirectories, loggerNameRoot, successorNodeLabelIdLookup);
            }
            else
            {
                LoopScopeNode loopScopeNode = node as LoopScopeNode;
                if (loopScopeNode != null)
                {
                    //loop scope does not need successor nodes lookups, so pass in empty dictionary
                    Dictionary <string, string> successorNodeLabelIdLookup = new Dictionary <string, string>();
                    CompileDecisionInternal(loopScopeNode, experiment, workspaceTypesDirectories, loggerNameRoot, successorNodeLabelIdLookup);
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Builds the source of decision module and compile decision module into the assembly
        /// </summary>
        /// <param name="metadata">The metadata.</param>
        /// <param name="successorNodeLabelIdLookup">The successor node label id lookup.</param>
        /// <param name="predeccessorsOutputsNameTypeLookup">The predeccessors outputs name type lookup.</param>
        /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        private static void BuildSourceAndCompileDecisionModule(IDecision metadata, Dictionary <string, string> successorNodeLabelIdLookup,
                                                                Dictionary <string, string> predeccessorsOutputsNameTypeLookup,
                                                                List <string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
        {
            metadata.FireRequestLatestCode();

            //create local componentlogger (ComponentLoggerImplementation implements MarshalByRefObject, thanks to which it can pass logs between appdomains
            TraceLabSDK.ComponentLogger logger = LoggerFactory.CreateLogger(loggerNameRoot, metadata.UniqueDecisionID, metadata);

            //construct the final code, and collect types assemblies locations to be referenced by the compilator
            HashSet <string> assembliesReferenceLocations;
            string           finalDecisionModuleSourceCode = DecisionCodeBuilder.BuildCodeSource(metadata, workspaceTypesDirectories,
                                                                                                 successorNodeLabelIdLookup, predeccessorsOutputsNameTypeLookup, logger, out assembliesReferenceLocations);

            // Create the new domain with whatever current security evidence we're running with using the library helper
            LibraryHelper helper = new LibraryHelper(workspaceTypesDirectories);

            AppDomain newDomain = helper.CreateDomain("DecisionModuleCompilation");

            newDomain.Load(Assembly.GetExecutingAssembly().GetName());
            helper.PreloadWorkspaceTypes(newDomain);

            //// Load our output assembly into the other domain.
            DecisionModuleCompilator compiler =
                (DecisionModuleCompilator)newDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(DecisionModuleCompilator).FullName,
                                                                            false,
                                                                            BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance | BindingFlags.Instance, null,
                                                                            new object[] { },
                                                                            System.Globalization.CultureInfo.CurrentCulture, new object[] { });

            compiler.CompileDecisionModule(finalDecisionModuleSourceCode, metadata.SourceAssembly, assembliesReferenceLocations);

#if !MONO_DEV
            //when developing on mono in MonoDevelop application crashes when unloading appdomain.
            //it only happens from within of MonoDevelop with attached debugger. Running normally, works fine.
            AppDomain.Unload(newDomain);
#endif
        }
 /// <summary>
 /// Adds the node.
 /// </summary>
 /// <param name="id">The id.</param>
 /// <param name="metadata">The metadata.</param>
 /// <param name="loggerNameRoot">The logger name root.</param>
 public abstract void AddNode(String id, Metadata metadata, LoggerNameRoot loggerNameRoot);
Exemple #17
0
 public RunnableNode CreateNode(string id, Metadata metadata, LoggerNameRoot loggerNameRoot, TraceLab.Core.Components.ComponentsLibrary library, AppDomain componentsAppDomain,
                                System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
 {
     return(CreateNode(id, metadata, terminateExperimentExecutionResetEvent));
 }
Exemple #18
0
        /// <summary>
        /// Validates the entire experiment.
        /// It validates the structure of the experimental graph,
        /// validates all inputs and outputs,
        /// checks if all components are in the component library.
        /// </summary>
        /// <param name="experiment">The experiment.</param>
        /// <returns>true if there is no errors, false, if errors has been detected</returns>
        public static bool ValidateExperiment(IExperiment experiment, List <string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
        {
            List <ExperimentNode>           vertices;
            List <ExperimentNodeConnection> edges;

            return(ValidateExperiment(experiment, out vertices, out edges, workspaceTypesDirectories, true, loggerNameRoot));
        }