HPCCommunity.org
 
Register

Go Back   HPC Community - High Performance Computing (HPC) Community > Symphony Developer Edition (DE) > Symphony DE Articles and Helpful Tips > Development and Debugging Tips

Development and Debugging Tips Share development and debugging tips for Symphony DE.

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old July 11th, 2008, 06:56 AM
Young's Avatar
Junior Member
 
Join Date: March 5th, 2008
Location: Toronto, Canada
Posts: 58
Blog Entries: 1
Send a message via Skype™ to Young
Default Catching interrupt events from service becomes easy in Symphony DE 4.0

Catching interrupt events from your application's service code was an error-prone, manual and inefficient task in previous versions of Symphony (3.2 and earlier).

For example, here is a C# Symphony service written for Symphony 3.2. It tries to catch and handle KILL events caused by killing a session. The sample code below first makes a temporary directory in onSessionEnter and the temporary directory is deleted at onSessionLeave.

When the session gets killed, the service attempts to delete the directory at onInvoke by catching the KILL event using the InterruptEvent object.

Code:
public override void OnInvoke(TaskContext taskContext)
{
    try 
    {
        do 
        {
            InterruptEvent iEvent = serviceContext.LastInterruptEvent;
            if (iEvent.EventCode != InterruptEventCode.None)
            {
                // Terminate Decendant Processes and Remove Working Dir
                try 
                {
                    // Remove Working Dir here
                }
                catch {}
        
                if (iEvent.EventCode == InterruptEventCode.SessionSuspended)
                {
                    // Some actions for session suspend
                }
                else 
                {
                    // Some actions for session kill
                }
            }
        } 
        while (!se.WaitForExit(WAIT_PERIOD));        // Just rotate "while" several times
    }
    catch (StandardExecutorException e)
    {
        // Reaction for exception
    }
    catch (SoamException e) 
    { 
        // Reaction for exception
    }
    catch (Exception e)
    {
        // Reaction for exception
    }
}
Failure to match up the WAIT_PERIOD above and the taskCleanupPeriod in the <Session> section of your application profile may cause the service to miss the session KILL event.

In previous versions of Symphony, you had to go through the hassle of manually setting taskCleanupPeriod to be always greater than the WAIT_PERIOD. Also, this way of polling for an event is not efficient.

For usability and efficiency reasons, Symphony 4.0 introduced onServiceInterrupt(), an event-based callback method. Inside the implementation of onServiceInterrupt, you can retrieve the last caught event through the method getLastInterruptEvent() in the ServiceContext class as shown in the sample service code below. The method will return the gracePeriod set as the taskCleanupPeriod in the application profile and you don't have to worry about the service prematurely exiting without doing the necessary operations.

Code:
public override void OnServiceInterrupt(ServiceContext serviceContext)
        {
            //@@onInterrupt_GLOBAL@@

            const string fname="onServiceInterrupt()";
            m_serviceOutput.WriteLine(fname + ": enter");

            // print interrupt information
            InterruptEvent eve = serviceContext.LastInterruptEvent;

            string eventString;
            switch(eve.EventCode)
            {
                case InterruptEventCode.TaskKilled:
                    eventString = "TaskKilled";
                    break;
                case InterruptEventCode.TaskSuspended:
                    eventString = "TaskSuspended";
                    break;
                default:
                    eventString = "Unkown";
                    break;
            }

            m_serviceOutput.WriteLine("InterruptEvent = " + eventString + ", gracePeriod = " + eve.GracePeriod + "ms");


            closeDB(fname);

            m_serviceOutput.WriteLine(fname + ": exit");
            m_serviceOutput.WriteLine();
            m_serviceOutput.Flush();

            // close the stream
            m_serviceOutput.Close();
        }

        // simulate connection to DB
        private void connectDB()
        {
            m_serviceOutput.WriteLine("connected to DB.");
            m_serviceOutput.Flush();
        }

        // simulate some processing in DB with the given arguments
        private void processDB(int iter, int sleep)
        {
            //no-op
        }

        // simulate closing connection DB
        private void closeDB(string fname)
        {
            m_serviceOutput.WriteLine("CONNECTION TO DB CLOSED IN " + fname);
            m_serviceOutput.Flush();
        }

        // simulate some intensive operation is happening.
        private void intensiveOp(int iter, int sleepTime)
        {
            // supposedly intensive operation
            m_result += iter + sleepTime;
            Thread.Sleep(sleepTime * 1000);
        }

    }
You can find the complete sample code for onServiceInterrupt under %SOAM_HOME%/4.0/samples.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Forum Jump


All times are GMT. The time now is 09:38 PM.


Powered by vBulletin® Version 3.8.0 Release Candidate 1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.