예제 #1
0
        /// <summary>
        /// Process actions in parallel.
        /// </summary>
        /// <param name="state"></param>
        protected override void Process(object state)
        {
            lock (m_actions)
            {
                // Init expected count. Lock is not needed since we don't expect app to add task while executing sequence but there is no harm.
                m_expectedCount = m_actions.Count;
            }
            bool done = false;

            while (!done)
            {
                AsyncTask task = null;
                lock (m_actions)
                {
                    if (m_actions.Count > 0)
                    {
                        task = m_actions.Dequeue();
                    }
                }
                if (task == null)
                {
                    done = true; // No more actions to execute.
                }
                else
                {
                    Exception exception = null;
                    task.TaskCompleted +=
                        delegate(object sender, AsyncTaskCompletedEventArgs e)
                    {
                        this.Logger.Log(Logger.LogLevel.Info, String.Format("**{0}({1})** <{2}> Started.", this.Name, this.Component.Name, task.Name));
                        this.AddCompletedAction(task);         // Could have failed or succeeded. The method should take care of this.
                    };
                    try
                    {
                        this.Logger.Log(Logger.LogLevel.Info, String.Format("**{0}({1})** <{2}> Starting.", this.Name, this.Component.Name, task.Name));
                        task.StartTask();
                    }
                    catch (RealTimeException rte)
                    {
                        exception = rte;
                    }
                    catch (InvalidOperationException ivo)
                    {
                        exception = ivo;
                    }
                    finally
                    {
                        if (exception != null)
                        {
                            this.Logger.Log(Logger.LogLevel.Info, String.Format("**{0}({1})** Completed <{2}> with exception. {3}",
                                                                                this.Name, this.Component.Name, task.Name, exception.ToString()));
                            this.AddCompletedAction(task); // This task resulted in exception.
                        }
                    }
                }
            }
            if (m_expectedCount == 0)
            {
                // It was empty list of actions to start with.
                this.CompleteSequence(null);
            }
        }
예제 #2
0
        /// <summary>
        /// Process Sequence serially.
        /// </summary>
        protected virtual void Process(object state)
        {
            AsyncTaskResult previousActionResult = state as AsyncTaskResult; // Can be null.
            AsyncTask       task = null;

            lock (m_actions)
            {
                m_pendingAction = null;
                if (m_actions.Count > 0)
                {
                    task            = m_actions.Dequeue();
                    m_pendingAction = task;
                }
            }
            if (task == null)
            {
                // No more items in queue. Complete the starup operaton if needed.
                this.CompleteSequence(null);
            }
            else
            {
                Exception exception = null;
                try
                {
                    task.TaskCompleted +=
                        delegate(object sender, AsyncTaskCompletedEventArgs e)
                    {
                        AsyncTask reportingAction = sender as AsyncTask;
                        if (!Object.ReferenceEquals(reportingAction, task))
                        {
                            this.Logger.Log(Logger.LogLevel.Warning,
                                            String.Format("Reporting task does not match pending task. Task is probably completing twice. Task = {0}", reportingAction.Name));
                            return;     // Ignore this reporting.
                        }
                        if (task.Exception != null && this.Component.Logger != null)
                        {
                            this.Component.Logger.Log(Logger.LogLevel.Verbose,
                                                      String.Format("<{0}> completed with exception.", task.Name), task.Exception);
                        }
                        else
                        {
                            this.Component.Logger.Log(Logger.LogLevel.Verbose,
                                                      String.Format("**{0}({1})** <{2}> Completed Task.",
                                                                    this.Name, this.Component.Name, task.Name));
                        }
                        bool      completionNeeded = false;
                        Exception ex = task.Exception;
                        if (task.Exception != null && !task.IsOptional)
                        {
                            completionNeeded = true;
                        }
                        if (completionNeeded)
                        {
                            this.CompleteSequence(ex);
                        }
                        else
                        {
                            // Make sure the task chained previous result, if any.
                            if (previousActionResult != null)
                            {
                                AsyncTaskResult currActionResult = e.ActionResult;
                                if (currActionResult == null)     // This should not be null if Task always returned it. Play safe.
                                {
                                    currActionResult = new AsyncTaskResult(task.Exception);
                                }
                                // If the task completing has task result, then we need to chain. If not create a new one.
                                currActionResult.PreviousActionResult = previousActionResult;
                            }
                            // Continue processing.
                            System.Threading.ThreadPool.QueueUserWorkItem(this.Process, e.ActionResult);
                        }
                    };
                    this.Component.Logger.Log(Logger.LogLevel.Verbose,
                                              String.Format("**{0}({1})** <{2}> Started Task.",
                                                            this.Name, this.Component.Name, task.Name));
                    task.PreviousActionResult = previousActionResult;
                    task.StartTask();
                }
                catch (RealTimeException rte)
                {
                    exception = rte;
                }
                catch (InvalidOperationException ivo)
                {
                    exception = ivo;
                }
                finally
                {
                    if (exception != null && !task.IsOptional)
                    {
                        this.Component.Logger.Log(Logger.LogLevel.Verbose,
                                                  String.Format("**{0}({1})** Completing due to exception while starting <{2}>.",
                                                                this.Name, this.Component.Name, task.Name), exception);
                        this.CompleteSequence(exception);
                    }
                    else if (exception != null)
                    {
                        this.Component.Logger.Log(Logger.LogLevel.Verbose, String.Format("**{0}({1})** resuming after exception while starting <{2}>.",
                                                                                         this.Name, this.Component.Name, task.Name), exception);
                        // Continue processing. Ignore failuer in task.
                        System.Threading.ThreadPool.QueueUserWorkItem(this.Process);
                    }
                    // else, wait for the task to complete.
                }
            }
        }
예제 #3
0
        public void CreateOrGetUserEndpoint(AsyncTask task, object state)
        {
            string ownerUri = state as string;

            if (String.IsNullOrEmpty(ownerUri))
            {
                task.Complete(new InvalidOperationException("OwnerUri is needed to request a user endpoint."));
                return;
            }
            RealTimeAddress ownerAddress = null;

            try
            {
                ownerAddress = new RealTimeAddress(ownerUri);
            }
            catch (ArgumentException exception)
            {
                task.Complete(exception);
                return;
            }
            MyUserEndpoint myUserEndpoint = null;

            lock (this.SyncRoot)
            {
                if (m_userEndpoints.ContainsKey(ownerAddress))
                {
                    myUserEndpoint = m_userEndpoints[ownerAddress];
                    if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Terminating || myUserEndpoint.UserEndpoint.State == LocalEndpointState.Terminated)
                    {
                        myUserEndpoint = null; // Loose it since it is going away.
                        m_userEndpoints.Remove(ownerAddress);
                        m_userEndpointReferenceCounts.Remove(ownerAddress);
                    }
                    else
                    {
                        int count = m_userEndpointReferenceCounts[ownerAddress];
                        count++;
                        m_userEndpointReferenceCounts[ownerAddress] = count;
                    }
                }
                if (myUserEndpoint == null)
                {
                    // Create and add user endpoint into dictionary.
                    // One could use the platform discover server from uri if the topology has DNS srv records for server auto discovery.
                    // Normally, this would point to a director. Here, we will use the proxy of the application endpoint.
                    UserEndpointSettings userEndpointSettings = new UserEndpointSettings(ownerUri, m_settings.ProxyHost, m_settings.ProxyPort);
                    UserEndpoint         userEndpoint         = new UserEndpoint(m_parent.Platform, userEndpointSettings);
                    myUserEndpoint = new MyUserEndpoint(userEndpoint);
                    m_userEndpoints.Add(ownerAddress, myUserEndpoint);
                    m_userEndpointReferenceCounts.Add(ownerAddress, 1);
                    myUserEndpoint.UserEndpoint.StateChanged += UserEndpointStateChanged; // Ensures that only one registration per endpoint.
                }
                UserEndpointCreationActionResult result = new UserEndpointCreationActionResult(myUserEndpoint, null);
                task.TaskResult = result; // Store it for now.
                if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Established)
                {
                    task.Complete(null, result);
                }
                else if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Establishing)
                {
                    // Wait till the endpoint establish completes.
                    lock (this.SyncRoot)
                    {
                        m_pendingUserEndpointCreationTasks.Add(task);
                    }
                }
                else if (myUserEndpoint.UserEndpoint.State == LocalEndpointState.Idle)
                {
                    AsyncTask establishTask = new AsyncTask(this.StartupUserEndpoint, myUserEndpoint.UserEndpoint);
                    establishTask.TaskCompleted +=
                        delegate(object sender, AsyncTaskCompletedEventArgs e)
                    {
                        task.TaskResult.Exception = e.ActionResult.Exception;     // Transfer
                        task.Complete(e.ActionResult.Exception, task.TaskResult);
                        lock (this.SyncRoot)
                        {
                            // Complete pending tasks
                            foreach (AsyncTask pendingTask in m_pendingUserEndpointCreationTasks)
                            {
                                pendingTask.TaskResult.Exception = e.ActionResult.Exception;
                                pendingTask.Complete(e.ActionResult.Exception, pendingTask.TaskResult);
                            }
                            m_pendingUserEndpointCreationTasks.Clear();
                        }
                    };
                    establishTask.StartTask();
                }
            }
        }