I wish to implement composite service using threading in webMethods. I’m planning to invoke multiple wrapper services through Service.doThreadInvoke() within java service. Once different services are invoked using threads, wait service will be used to wait for the completion of those services invoked. Finally the response from all the services will be consolidated and sent back to the client application. How to name the thread (service) uniquely because that is the input for the pub.sync:wait service? If there is any code snippet that would be helpful.
You define the key you want to use. Use a GUID. Or perhaps the output of pub.date:currentNanoTime (though there are collision risks with that). Or there are ways to get the root context ID of the service that running (your top-level service) which is a GUID. Anything that is unique.
I would urge a bit of caution though. On the surface it seems logical that making multiple calls all at once and collecting responses will be faster than calling each system serially. It may indeed end up faster but consider:
- How much faster is it? Is it meaningful? Does it really matter if the response is returned in 3 seconds instead of 5 seconds?
- What will be done when one of the systems doesn’t respond in time or not at all?
Make sure the added complexity of the code, and additional troubleshooting when things go wrong, is offset by a real need to be faster. If this service is supporting an “unattended” integration (e.g. no user is waiting for a response) then I’d recommend not taking this approach – the complexity won’t be worth it.
Sorry for the delay. I had internet issues, so couldn’t respond immediately. Thank you for your reply. how to send the GUID (unique key) to service invoked as thread? Is there any specific method or way through which I can attach (name) a service with unique key? If possible, please paste a code snippet. That would be helpful to me.
In looking at this a bit more deeply, you don’t want to use pub.sync:wait for this. I got focused on your question about the key, and the caveat of “do you really want to do this.”
What you’ll do is call doThreadInvoke() for each service you want to kick off in parallel. Each of them will return a ServiceThread object. Keep every ServiceThread – in a list/array.
Then loop over the list and call ServiceThread.getIData() for each. This will get the results for every call in turn. Then you combine the results, however needed, and return to the caller.
I would again urge caution. Make sure you really need to do this.
Please try java service below for async multiple services invocation.
'
public static final void invokeServices(IData pipeline) throws ServiceException {
IDataCursor inputCursor = pipeline.getCursor();
IData[] services = IDataUtil.getIDataArray(inputCursor, "services");
inputCursor.destroy();
int size = services.length;
ServiceThread [] threads = new ServiceThread[size];
IData [] outputs = new IData[size];
for (int i = 0; i < size; i++){
IData service = services[i];
IDataCursor serviceCursor = service.getCursor();
String serviceName = IDataUtil.getString(serviceCursor, "serviceName");
IData servicePipe = IDataUtil.getIData(serviceCursor, "servicePipe");
threads[i] = Service.doThreadInvoke(NSName.create(serviceName), servicePipe);
serviceCursor.destroy();
}
for (int i = 0; i < services.length; i++){
try {
outputs[i] = threads[i].getIData();
} catch (Exception e) {
e.printStackTrace();
}
}
IDataCursor outputCursor = pipeline.getCursor();
IDataUtil.put(outputCursor, "outputs", outputs);
outputCursor.destroy();
}
Inputs:
services - Document List
?serviceName - String
?servicePipe - Document
Outputs:
outputs - Document List