Ignore:
Timestamp:
Jun 5, 2010, 3:19:15 PM (12 years ago)
Author:
kopal
Message:
  • replaced own threading in ExecutionEngine with Gears4Net
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/WorkspaceManager/Execution/ExecutionEngine.cs

    r1562 r1590  
    2525using Cryptool.PluginBase;
    2626using System.Reflection;
     27using Gears4Net;
    2728
    2829namespace WorkspaceManager.Execution
     
    3334    public class ExecutionEngine
    3435    {
    35         private Hashtable RunningPlugins = Hashtable.Synchronized(new Hashtable());
    3636        private WorkspaceManager WorkspaceManagerEditor;
    37         private Mutex mutex = new Mutex();
    38 
    39         /// <summary>
    40         /// Enable/Disable the Debug Mode
    41         /// </summary>
    42         public bool DebugMode { get; set; }
    43 
     37        private Scheduler scheduler;
     38     
    4439        /// <summary>
    4540        /// Creates a new ExecutionEngine
     
    6560        /// <param name="workspaceModel"></param>
    6661        public void Execute(WorkspaceModel workspaceModel)
    67         {           
    68             RunningPlugins.Clear();
    69             GuiLogMessage("ExecutionEngine starts", NotificationLevel.Debug);
    70             ThreadPool.SetMaxThreads(1, 1);
    71             ThreadPool.QueueUserWorkItem(new WaitCallback(Schedule), workspaceModel);
    72         }
    73 
    74         /// <summary>
    75         /// Scheduler Thread
    76         /// </summary>
    77         /// <param name="stateInfo"></param>
    78         public void Schedule(object stateInfo)
    79         {
    80             WorkspaceModel workspaceModel = (WorkspaceModel)stateInfo;
     62        {
    8163            if (!IsRunning)
    8264            {
    8365                IsRunning = true;
     66                scheduler = new WinFormsScheduler("Scheduler");
    8467                workspaceModel.resetStates();
    85 
    86                 //Initially check if a plugin can be executed
     68               
    8769                foreach (PluginModel pluginModel in workspaceModel.AllPluginModels)
    8870                {
    89                     pluginModel.checkExecutable();
     71                    PluginProtocol pluginProtocol = new PluginProtocol(scheduler, pluginModel,this);
     72                    PluginModel.PluginProtocol = pluginProtocol;
     73                    scheduler.AddProtocol(pluginProtocol);
     74                    pluginModel.checkExecutable(pluginProtocol);
     75                    pluginProtocol.Start();
    9076                }
    91 
    92                 //Now start Plugins if they are executable
    93                 while (IsRunning)
    94                 {
    95                     foreach (PluginModel pluginModel in workspaceModel.AllPluginModels)
    96                     {
    97                        
    98                         //execute the plugin in a new Thread only if it is executable
    99                         if (IsRunning && pluginModel.ExecutionState == PluginModelState.Executable && !RunningPlugins.Contains(pluginModel))
    100                         {
    101                             AddRunningPlugin(pluginModel);
    102                             ThreadPool.QueueUserWorkItem(new WaitCallback(runPlugin), pluginModel);
    103                         }
    104                         Thread.Sleep(50);
    105                     }
    106                 }
    107                 GuiLogMessage("ExecutionEngine ends", NotificationLevel.Debug);
    10877            }
    109         }
    110 
    111         /// <summary>
    112         /// Runs a Plugin
    113         /// </summary>
    114         /// <param name="stateInfo"></param>
    115         private void runPlugin(object stateInfo)
    116         {   
    117          
    118             PluginModel pluginModel = (PluginModel)stateInfo;           
    119             GuiLogMessage("Running Plugin " + pluginModel.Name + " now!", NotificationLevel.Debug);
    120            
     78        }     
     79     
     80        /// <summary>
     81        /// Stop the execution
     82        /// </summary>
     83        public void Stop()
     84        {
     85            scheduler.Shutdown();
     86            IsRunning = false;   
     87        }
     88
     89        /// <summary>
     90        /// Pause the execution
     91        /// </summary>
     92        public void Pause()
     93        {
     94            //not implemented yet
     95        }
     96
     97        /// <summary>
     98        /// Use the logger of the WorkspaceManagerEditor
     99        /// </summary>
     100        /// <param name="message"></param>
     101        /// <param name="level"></param>
     102        public void GuiLogMessage(string message, NotificationLevel level)
     103        {           
     104            WorkspaceManagerEditor.GuiLogMessage(message, level);
     105        }           
     106    }
     107
     108    /// <summary>
     109    /// Message send to scheduler for a Plugin to trigger the PreExecution
     110    /// </summary>
     111    public class MessagePreExecution : MessageBase
     112    {
     113        public PluginModel PluginModel;
     114    }
     115
     116    /// <summary>
     117    /// Message send to scheduler for a Plugin to trigger the Execution
     118    /// </summary>
     119    public class MessageExecution : MessageBase
     120    {
     121        public PluginModel PluginModel;
     122    }
     123
     124    /// <summary>
     125    /// Message send to scheduler for a Plugin to trigger the PostExecution
     126    /// </summary>
     127    public class MessagePostExecution : MessageBase
     128    {
     129        public PluginModel PluginModel;
     130    }
     131
     132     /// <summary>
     133    /// A Protocol for a PluginModel
     134    /// </summary>
     135    public class PluginProtocol : ProtocolBase
     136    {
     137        private PluginModel pluginModel;
     138        private ExecutionEngine executionEngine;
     139
     140        /// <summary>
     141        /// Create a new protocol. Each protocol requires a scheduler which provides
     142        /// a thread for execution.
     143        /// </summary>
     144        /// <param name="scheduler"></param>
     145        public PluginProtocol(Scheduler scheduler, PluginModel pluginModel,ExecutionEngine executionEngine)
     146            : base(scheduler)
     147        {
     148            this.pluginModel = pluginModel;
     149            this.executionEngine = executionEngine;
     150        }
     151
     152        /// <summary>
     153        /// The main function of the protocol
     154        /// </summary>
     155        /// <param name="stateMachine"></param>
     156        /// <returns></returns>
     157        public override System.Collections.Generic.IEnumerator<ReceiverBase> Execute(AbstractStateMachine stateMachine)
     158        {
     159            yield return Receive<MessagePreExecution>(null, this.HandlePreExecute);
     160            MessageExecution msg_exec = new MessageExecution();
     161            msg_exec.PluginModel = this.pluginModel;
     162            this.BroadcastMessage(msg_exec);           
     163            yield return Receive<MessageExecution>(null, this.HandleExecute);
     164            MessagePostExecution msg_post = new MessagePostExecution();
     165            msg_post.PluginModel = this.pluginModel;
     166            this.BroadcastMessage(msg_post);   
     167            yield return Receive<MessagePreExecution>(null, this.HandlePostExecute);
     168        }
     169
     170        /// <summary>
     171        /// Handler function for a message.
     172        /// This handler must not block, because it executes inside the thread of the scheduler.
     173        /// </summary>
     174        /// <param name="msg"></param>
     175        private void HandlePreExecute(MessagePreExecution msg)
     176        {
     177            executionEngine.GuiLogMessage("HandlePreExecute for \"" + msg.PluginModel.Name + "\"", NotificationLevel.Debug);
     178            msg.PluginModel.Plugin.PreExecution();
     179        }
     180
     181        /// <summary>
     182        /// Handler function for a message.
     183        /// This handler must not block, because it executes inside the thread of the scheduler.
     184        /// </summary>
     185        /// <param name="msg"></param>
     186        private void HandleExecute(MessageExecution msg)
     187        {
     188            executionEngine.GuiLogMessage("HandleExecute for \"" + msg.PluginModel.Name + "\"", NotificationLevel.Debug);
    121189            //Fill the plugins Inputs with data
    122190            foreach (ConnectorModel connectorModel in pluginModel.InputConnectors)
    123191            {
    124192                if (connectorModel.HasData)
    125                 {                   
     193                {
    126194                    PropertyInfo propertyInfo = pluginModel.Plugin.GetType().GetProperty(connectorModel.PropertyName);
    127                     GuiLogMessage("Setting for " + connectorModel.PluginModel.Name + " the value of property " + propertyInfo.Name + " to \"" + connectorModel.Data +"\"", NotificationLevel.Debug);
    128                     propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);   
     195                    propertyInfo.SetValue(pluginModel.Plugin, connectorModel.Data, null);
    129196                    connectorModel.Data = null;
    130197                    connectorModel.HasData = false;
     
    132199                }
    133200            }
    134 
    135             //Run execution
    136             try
    137             {
    138                 pluginModel.ExecutionState = PluginModelState.PreExecuting;
    139                 pluginModel.Plugin.PreExecution();
    140                 pluginModel.ExecutionState = PluginModelState.Executing;
    141                 pluginModel.Plugin.Execute();
    142                 pluginModel.ExecutionState = PluginModelState.PostExecuting;
    143                 pluginModel.Plugin.PostExecution();
    144                 pluginModel.ExecutionState = PluginModelState.Terminated;
    145             }
    146             catch (Exception ex)
    147             {
    148                 pluginModel.ExecutionState = PluginModelState.Error;
    149                 GuiLogMessage("Error during Execution of Plugin " + pluginModel.Name + ": " + ex.Message, NotificationLevel.Error);
    150             }
    151             //Remove plugin from being-executed-list so that it can be
    152             //executed again
    153             if (IsRunning)
    154             {
    155                 //we only remove the plugin if we are in state running;otherwise
    156                 //the Stop() method will remove it
    157                 RemoveRunningPlugin(pluginModel);
    158             }
    159             GuiLogMessage("Stopped Plugin " + pluginModel.Name, NotificationLevel.Debug);
    160             Thread.Sleep(15);
    161         }
    162 
    163         /// <summary>
    164         /// Stop the execution
    165         /// </summary>
    166         public void Stop()
    167         {
    168             mutex.WaitOne();
    169             IsRunning = false;
    170             foreach (PluginModel pluginModel in RunningPlugins.Keys)
    171             {
    172                 pluginModel.Plugin.Stop();             
    173             }
    174             RunningPlugins.Clear();
    175             mutex.ReleaseMutex();
    176         }
    177 
    178         /// <summary>
    179         /// Pause the execution
    180         /// </summary>
    181         public void Pause()
    182         {
    183             //not implemented yet
    184         }
    185 
    186         /// <summary>
    187         /// Use the logger of the WorkspaceManagerEditor
    188         /// </summary>
    189         /// <param name="message"></param>
    190         /// <param name="level"></param>
    191         private void GuiLogMessage(string message, NotificationLevel level)
    192         {
    193             if (DebugMode || level.Equals(NotificationLevel.Error) || level.Equals(NotificationLevel.Warning))
    194             {
    195                 WorkspaceManagerEditor.GuiLogMessage(message, level);
    196             }
    197         }
    198 
    199         /// <summary>
    200         /// Add a running plugin
    201         /// </summary>
    202         /// <param name="pluginModel"></param>
    203         private void AddRunningPlugin(PluginModel pluginModel)
    204         {
    205             mutex.WaitOne();
    206             if (IsRunning)
    207             {
    208                 RunningPlugins.Add(pluginModel, pluginModel);
    209             }
    210             mutex.ReleaseMutex();
    211         }
    212 
    213         /// <summary>
    214         /// Remove a running plugin
    215         /// </summary>
    216         /// <param name="pluginModel"></param>
    217         private void RemoveRunningPlugin(PluginModel pluginModel)
    218         {
    219             mutex.WaitOne();
    220             if(RunningPlugins.Contains(pluginModel))
    221             {
    222                 RunningPlugins.Remove(pluginModel);
    223             }
    224             mutex.ReleaseMutex();
    225         }
    226 
     201            msg.PluginModel.Plugin.Execute();
     202        }
     203
     204        /// <summary>
     205        /// Handler function for a message.
     206        /// This handler must not block, because it executes inside the thread of the scheduler.
     207        /// </summary>
     208        /// <param name="msg"></param>
     209        private void HandlePostExecute(MessagePreExecution msg)
     210        {
     211            executionEngine.GuiLogMessage("HandlePostExecute for \"" + msg.PluginModel.Name + "\"", NotificationLevel.Debug);
     212            msg.PluginModel.Plugin.PostExecution();
     213        }
    227214    }
    228215}
Note: See TracChangeset for help on using the changeset viewer.