1. Objective
I have two different service implementations for my application:- One short running service generating output results
- One longer running service using result returned from first service as input
message
My client needs to execute both of them sequentially.

2. Configuration
In application profile:- Add a second SessionType named LongRunningTasks
- Add a second Service named SampleService2 assigned to the new SessionType, by setting serviceName="SampleService2"
- Set a different packageName for the new SessionType. This package will contain the second service binary to be executed.
- Define SampleServiceCPP to be default service. Session Type ShortRunningTasks uses default service.
- Optionally, define maxOtherInstances="1" for both services, to avoiding frequent shut down and restart of the SIs. Refer to Application Profile Reference for details.
- Optionally, configure the Session Types. To demonstrate, set recoverable=true for LongRunningTasks.
Code:
<SessionTypes>
<Type name="ShortRunningTasks" priority="1" recoverable="false"
sessionRetryLimit="3" taskRetryLimit="3"
abortSessionIfTaskFail="false" abortSessionIfClientDisconnect="true"
suspendGracePeriod="100" taskCleanupPeriod="100"/>
</SessionTypes>
<SessionTypes>
<Type name="LongRunningTasks" priority="1" recoverable="true"
serviceName="SampleService2" sessionRetryLimit="3" taskRetryLimit="3"
abortSessionIfTaskFail="false" abortSessionIfClientDisconnect="true"
suspendGracePeriod="100" taskCleanupPeriod="100"/>
</SessionTypes>
<Service maxOtherInstances="1" default="true" description="The Sample Service"
name="SampleService" packageName="SampleServiceCPP">
....
</Service>
<Service maxOtherInstances="1" description="The Sample Service"
name="SampleService2" packageName="SampleServiceCPP2">
....
</Service>
3. Code
In client application (I used samples/CPP/SampleApp/SyncClient for demonstration):- Save output result from first session (1 task)
- Create a second session with its own attributes
- Submit 1 task for this session
- Fetch task result and display output
Code:
// Now get our results - will block here until all tasks retrieved
EnumItemsPtr enumOutput = sesPtr->fetchTaskOutput(tasksToSend);
std::string str = "";
// Inspect results
TaskOutputHandlePtr output;
while(enumOutput->getNext(output))
{
// Check for success of task
if (true == output->isSuccessful())
{
// Get the message returned from the service
MyMessage outMsg;
output->populateTaskOutput(&outMsg);
// Display content of reply
cout << "Task Succeeded [" << output->getId() << "]" << endl;
cout << "Integer Value : " << outMsg.getInt() << endl;
cout << outMsg.getString() << endl;
// Create message for second session, using output from first
str += outMsg.getString();
}
else
{
// Get the exception associated with this task
SoamExceptionPtr ex = output->getException();
cout << "Task Failed : " << ex->what() << endl;
}
}
// After result retrieved from first session,
// set up session creation attributes for second session
SessionCreationAttributes attributes2;
attributes2.setSessionName("mySession");
attributes2.setSessionType("LongRunningTasks");
attributes2.setSessionFlags(Session::ReceiveSync);
// Create a second synchronous session
SessionPtr sesPtr2 = conPtr->createSession(attributes2);
// Retrieve and print session ID
cout << "Session ID:" << sesPtr2->getId() << endl;
int tasksToSend2 = 1;
for (int taskCount = 0; taskCount < tasksToSend2; taskCount++)
{
MyMessage inMsg2(taskCount, true, const_cast<char*>(str.c_str()));
// Create task attributes
TaskSubmissionAttributes attrTask2;
attrTask2.setTaskInput(&inMsg2);
// send it
TaskInputHandlePtr input2 = sesPtr2->sendTaskInput(attrTask2);
// Retrieve and print task ID
cout << "task submitted with ID : " << input2->getId() << endl;
}
// Now get our results - will block here until all tasks retrieved
EnumItemsPtr enumOutput2 = sesPtr2->fetchTaskOutput(tasksToSend);
// Inspect results
...
In service application (I used samples/CPP/SampleApp/Service for demonstration):- For the first service (SampleServiceCPP), use existing Sampple Service code
- For the second service (SampleServiceCPP2), modify output message and insert sleep() to differentiate between the 2 services
Code:
virtual void onInvoke(TaskContextPtr& taskContext)
{
/********************************************************************
* Do your service logic here. This call applies to each task
* submission.
********************************************************************/
// Get the input that was sent from the client
MyMessage inMsg;
taskContext->populateTaskInput(inMsg);
// We simply echo the data back to the client
MyMessage outMsg;
outMsg.setInt(inMsg.getInt());
std::string str = "you sent : ";
str += inMsg.getString();
str += "\nwe replied : Hello Client !! This is Service 2\n>>> ";
sleep(1000);
...
}
4. Service Deployment
Deploy the second service, with packageName matching the one defined in application profile:
Code:
lechen@ib08b05-930: soamdeploy view
PACKAGE APPLICATION CONSUMER CREATED TIME
SampleServiceCPP SampleAppCPP /SampleAppCPP Thu May 1 16:11:07 2008
SampleServiceCPP2 SampleAppCPP /SampleAppCPP Sun May 4 02:04:18 2008
5. Execution
Submit the client:- Second session used output from first session as input
- Second session received output from second service
Code:
lechen@ib08b05-1051: Output/SyncClient
connection ID=47f87058-0000-1000-c000-00112529883c-42851248-7361
Session ID:907
task submitted with ID : 1
Task Succeeded [1]
Integer Value : 0
you sent : Hello Grid !!
we replied : Hello Client !!
>>> Synchronously.
Session ID:908
task submitted with ID : 1
Task Succeeded [1]
Integer Value : 0
you sent : you sent : Hello Grid !!
we replied : Hello Client !!
>>> Synchronously.
we replied : Hello Client !! This is Service 2
>>> Synchronously.
All Done !!
Observe that if we defined maxOtherInstances="1", the SIM keeps both SIs running concurrently. When either services need to be executed again, it will not have to be re-started.
Code:
lechen 10959 /opt/wa/4.0/linux2.4-glibc2.3-x86/etc/ssm -i ae317250-ffff-ffff-c000-00112529883c-104934320-7361 -u ib08b05.lsf.platform.com:52595 -a SampleAppCPP
lechen 10973 /opt/wa/4.0/linux2.4-glibc2.3-x86/etc/sim -u ib08b05.lsf.platform.com:56719 -i dc435780-ffff-ffff-c000-00112529883c-202804144-10959 -a SampleAppCPP
lechen 10979 /opt/wa/deploy/SampleAppCPP/SampleServiceCPP.v1/SampleServiceCPP
lechen 10991 /opt/wa/deploy/SampleAppCPP/SampleServiceCPP2.v3/SampleServiceCPP
6. Reference Document
Development Guide - Run multiple services in an application
Comments welcomed.