コード例 #1
0
        /// <summary>
        /// Runs the commands on the PlanetLab nodes.
        /// </summary>
        /// <param name="state">The manager state.</param>
        private void OnRunNodes(PlManagerState state)
        {
            lock (state.Sync)
            {
                // If the command has been stopped, return.
                if (state.IsStopped) return;

                // Compute the number of commands to execute.
                int commandCount = 0;
                foreach (PlCommand command in state.Slice.Commands)
                {
                    commandCount += command.HasParameters ? command.SetsCount : 1;
                }

                // Create a list of the pending nodes.
                foreach (PlNode node in state.Nodes)
                {
                    // If using only the nodes in the boot state, and the node is not in the boot state.
                    if (state.Slice.OnlyRunOnBootNodes && (node.GetBootState() != PlBootState.Boot))
                    {
                        // Raise a node disabled event.
                        if (null != this.NodeDisabled) this.NodeDisabled(this, new PlManagerNodeEventArgs(state, node));
                        // Skip processing this node.
                        continue;
                    }

                    // Raise a node enabled event.
                    if (null != this.NodeEnabled) this.NodeEnabled(this, new PlManagerNodeEventArgs(state, node, commandCount));

                    // Add the node to the list of pending nodes.
                    state.AddNode(node);
                }
            }

            // Compute the availability of worker threads for parallel processing.
            int availableWorkerThreads;
            int availableCompletionPortThreads;
            int maxWorkerThreads;
            int maxCompletionPortThreads;
            int maxParallel = Math.Max(state.Slice.RunParallelNodes, state.PendingCount);

            // Get the number of threads available on the thread pool.
            ThreadPool.GetAvailableThreads(out availableWorkerThreads, out availableCompletionPortThreads);
            // Get the maximum number of threads on the thread pool.
            ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxCompletionPortThreads);

            // If the number of available worker threads is smaller than the number of parallel nodes.
            if (availableWorkerThreads < maxParallel)
            {
                // Increment the number of maximum threads.
                ThreadPool.SetMaxThreads(
                    maxWorkerThreads + maxParallel - availableWorkerThreads,
                    maxCompletionPortThreads
                    );
            }

            lock (state.Sync)
            {
                // If the list of pending nodes is empty, stop.
                if (0 == state.PendingCount)
                {
                    this.Stop(state);
                }

                // Get a cached copy of all the pending PlanetLab nodes.
                int[] pendingCache = state.PendingNodes.ToArray();

                // For all the pending nodes.
                for (int index = 0; (index < pendingCache.Length) && (state.RunningCount < state.Slice.RunParallelNodes); index++)
                {
                    // Get the node state corresponding to the pending node.
                    PlManagerNodeState nodeState = state.GetNode(pendingCache[index]);

                    // If the slice configuration only allows one node per site.
                    if (state.Slice.OnlyRunOneNodePerSite)
                    {
                        // If the node site is completed.
                        if (state.IsSiteCompleted(nodeState.Node.SiteId.Value))
                        {
                            // Change the node from the pending to the skipped state.
                            state.UpdateNodePendingToSkipped(index);
                            // Raise an event indicating that the node has been skipped.
                            if (null != this.NodeSkipped) this.NodeSkipped(this, new PlManagerNodeEventArgs(state, nodeState.Node));
                            // Skip the loop to the next node.
                            continue;
                        }
                        // If the node site is running.
                        if (state.IsSiteRunning(nodeState.Node.SiteId.Value))
                        {
                            // Postpone the node for later, and skip the loop to the next node.
                            continue;
                        }
                    }

                    // Change the node from the pending to the running state.
                    state.UpdateNodePendingToRunning(index);

                    // Execute the commands on specified node.
                    this.OnRunNode(state, index);
                }
            }
        }