예제 #1
0
        /// <summary>
        /// Creates a request for property update from one vertex to another (one vertex is usually GM)
        /// </summary>
        /// <param name="replyEpr">Address to send response to</param>
        /// <param name="infos"></param>
        /// <param name="blockOnLabel"></param>
        /// <param name="blockOnVersion"></param>
        /// <param name="maxBlockTime"></param>
        /// <param name="getPropLabel"></param>
        /// <param name="ProcessStatistics"></param>
        /// <returns>Returns success/failure of thread startup</returns>
        public bool SetGetProps(string replyEpr, ProcessPropertyInfo[] infos, string blockOnLabel, ulong blockOnVersion, long maxBlockTime, string getPropLabel, bool ProcessStatistics)
        {
            DryadLogger.LogMethodEntry(replyEpr, this.DryadId);

            //
            // Check if graph manager is the one calling. If so, increment propertyWaiter count
            //
            if (ReplyDispatcher.IsGraphMrgUri(replyEpr))
            {
                int n = Interlocked.Increment(ref propertyWaiters);
            }

            //
            // Create new property request with provided parameters and queue up request sending
            //
            PropertyRequest req = new PropertyRequest(replyEpr, infos, blockOnLabel, blockOnVersion, maxBlockTime, getPropLabel, ProcessStatistics);

            bool result = ThreadPool.QueueUserWorkItem(new WaitCallback(SetGetPropThreadProc), req);

            DryadLogger.LogMethodExit(result);
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Creates a request for property update from one vertex to another (one vertex is usually GM)
        /// </summary>
        /// <param name="replyEpr">Address to send response to</param>
        /// <param name="infos"></param>
        /// <param name="blockOnLabel"></param>
        /// <param name="blockOnVersion"></param>
        /// <param name="maxBlockTime"></param>
        /// <param name="getPropLabel"></param>
        /// <param name="ProcessStatistics"></param>
        /// <returns>Returns success/failure of thread startup</returns>
        public bool SetGetProps(string replyEpr, ProcessPropertyInfo[] infos, string blockOnLabel, ulong blockOnVersion, long maxBlockTime, string getPropLabel, bool ProcessStatistics)
        {
            DryadLogger.LogMethodEntry(replyEpr, this.DryadId);

            //
            // Check if graph manager is the one calling. If so, increment propertyWaiter count
            //
            if (ReplyDispatcher.IsGraphMrgUri(replyEpr))
            {
                int n = Interlocked.Increment(ref propertyWaiters);
            }

            //
            // Create new property request with provided parameters and queue up request sending
            //
            PropertyRequest req = new PropertyRequest(replyEpr, infos, blockOnLabel, blockOnVersion, maxBlockTime, getPropLabel, ProcessStatistics);

            bool result = ThreadPool.QueueUserWorkItem(new WaitCallback(SetGetPropThreadProc), req);

            DryadLogger.LogMethodExit(result);
            return result;
        }
예제 #3
0
        /// <summary>
        /// Called in new thread in setgetproperty service operation
        /// </summary>
        /// <param name="obj"></param>
        void SetGetPropThreadProc(Object obj)
        {
            DryadLogger.LogMethodEntry(DryadId);
            PropertyRequest r = obj as PropertyRequest;

            ProcessInfo infoLocal = new ProcessInfo();

            ulong[]  propertyVersions = null;
            string[] propertyLabels   = null;

            //
            // Make sure process is started before continuing
            //
            if (this.State < ProcessState.Running)
            {
                try
                {
                    processStartEvent.WaitOne();
                }
                catch (ObjectDisposedException ex)
                {
                    // The process was cancelled and released before it started running, just return
                    if (exited)
                    {
                        DryadLogger.LogInformation("SetGetProp Thread", "Process {0} cancelled or exited before starting.", this.DryadId);
                    }
                    else
                    {
                        DryadLogger.LogError(0, ex);
                    }
                    DryadLogger.LogMethodExit();
                    return;
                }
            }

            //
            // Use status_pending if running, vertex initialization failure if process is failed and process exit code otherwise
            //
            infoLocal.processStatus = 0x103;  // WinNT.h STATUS_PENDING
            infoLocal.processState  = state;
            if (state == ProcessState.Running)
            {
                infoLocal.exitCode = 0x103; // WinNT.h STATUS_PENDING
            }
            else if (failed)
            {
                infoLocal.exitCode = Constants.DrError_VertexError;
            }
            else if (cancelled)
            {
                infoLocal.exitCode = Constants.DrError_VertexReceivedTermination;  // DryadError_VertexReceivedTermination
            }
            else
            {
                infoLocal.exitCode = (uint)systemProcess.ExitCode;
            }

            //
            // Record specified properties and update versions - wakes up anyone waiting for property changes
            //
            SetProperties(r.infos, out propertyLabels, out propertyVersions);

            //
            // Try to get property update
            //
            if (BlockOnProperty(r.blockOnLabel, r.blockOnVersion, r.maxBlockTime))
            {
                //
                // If property update was received, update the received property information
                // If received property marks vertex completed, record that
                //
                if (r.getPropLabel != null && r.getPropLabel.Length > 0)
                {
                    lock (syncRoot)
                    {
                        infoLocal.propertyInfos = new ProcessPropertyInfo[1];

                        int index;
                        if (TryGetProperty(r.getPropLabel, out infoLocal.propertyInfos[0], out index) == false)
                        {
                            DryadLogger.LogError(0, null, "Failed to get property for label {0}", r.getPropLabel);
                        }

                        if (StatusMessageContainsDryadError_VertexCompleted(infoLocal.propertyInfos[0].propertyLabel))
                        {
                            CopyProp(infoLocal.propertyInfos[0], out latestVertexStatusSent);
                        }
                    }
                }

                //
                // If request asks for statistics on vertex process, get them
                //
                if (r.ProcessStatistics)
                {
                    if (GetStatistics(out infoLocal.processStatistics) == false)
                    {
                        DryadLogger.LogError(0, null, "Failed to get vertex statistics");
                    }
                }
            }

            //
            // Try to report property change, if unsuccessful, kill the running vertex host process
            //
            if (!ReplyDispatcher.SetGetPropsComplete(r.replyUri, systemProcess, dryadProcessId, infoLocal, propertyLabels, propertyVersions))
            {
                try
                {
                    systemProcess.Kill();
                }
                catch (InvalidOperationException /* unused ioe */)
                {
                    // The process has already exited
                    // -or-
                    // There is no process associated with this Process object.
                }
                catch (Exception eInner)
                {
                    //
                    // all other exceptions
                    //
                    DryadLogger.LogError(0, eInner, "Exception calling back to '{0}'", r.replyUri);
                }
            }

            //
            // If a property was handled from the graph manager, decrement the waiter count
            //
            if (ReplyDispatcher.IsGraphMrgUri(r.replyUri))
            {
                int n = Interlocked.Decrement(ref propertyWaiters);
                DryadLogger.LogInformation("SetGetProp Thread", "Process {0} propertyWaiters = {1}", DryadId, n);
            }

            lock (syncRoot)
            {
                //
                // If vertex process has exited, and sending vertex completed event, we can stop worrying
                //
                if (!finalStatusMessageSent)
                {
                    if (latestVertexStatusSent != null)
                    {
                        if (!String.IsNullOrEmpty(latestVertexStatusSent.propertyString))
                        {
                            if (latestVertexStatusSent.propertyString.Contains(string.Format(@"(0x{0:x8})", Constants.DrError_VertexCompleted)))
                            {
                                finalStatusMessageSent = true;
                            }
                        }
                    }
                }
            }
            DryadLogger.LogMethodExit();
        }