Long calculation in a wcf restful service - wcf-rest

I have a WCF restful service and it works correctly, the problem is that the service expose a method "Calculate" and it may take several minutes to complete the calculation, and since REST is a stateless method, I'm running out of ideas !
should I maintain the session ?
how can I do a callback ?
10 minutes waiting for a response in a website is not convenient, but I have to find a solution.
PS: the service MUST be restful, and I cant reduce the calculation time.

I asked about your clients because if they were .Net only, you could implement the async programming model, but since they aren't...
You can do something like in this post - WCF Rest Asynchronous Calling Methods
Basically your method will spawn an additional thread to do the actual calculation work, and return some sort of token to the calling client immediately in the main thread. The client can then use this token in a polling method to check if the calculation is complete.

You can create a one-way WebMethod to submit the intial calculation request. Inside your calculation code, you need to update a database table or similiar with progress, either percentage or completion.
You will then need to create an additional 'Polling' method that you can use to check the status, using the previous table.
When your calculation method marks it as complete, you can then call a final 'GetResults' method which will do just that.
We do something similiar for large file imports that are submitted via web services and it works very well.
Some info;
http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapdocumentmethodattribute.oneway(v=vs.71).aspx

Related

Where to put calls to 3rd party APIs in Apigility/ZF2?

I have just completed my first API in Apigility. Right now it is basically a gateway to a database, storing and retrieving multi-page documents uploaded through an app.
Now I want to run some processing on the documents, e.g. process them through a 3rd party API or modify the image quality etc., and return them to the app users.
Where (in which class) do I generally put such logic? My first reflex would be to implement such logic in the Resource-Classes. However I feel that they will become quite messy, obstructing a clear view on the API's interface in the code and creating a dependency on a foreign API. Also, I feel limited because each method corresponds to an API call.
What if there is a certain processing/computing time? Meaning I cannot direct respond the result through a GET request. I thought about running an asynchronous process and send a push notification to the app, once the processing is complete. But again, where in the could would I ideally implement such processing logic?
I would be very happy to receive some architectural advice from someone who is more seasoned in developing APIs. Thank you.
You are able to use the zf-rest resource events to connect listeners with your additional custom logic without polluting your resources.
These events are fired in the RestController class (for example a post.create event here on line 382).
When you use Apigility-Doctrine module you can also use the events triggered in the DoctrineResource class (for example the DoctrineResourceEvent::EVENT_CREATE_POST event here on line 361) to connect your listeners.
You can use a queueing service like ZendQueue or something (a third party module) built on top of ZendQueue for managing that. You can find different ZF2 queueing systems/modules using Google.
By injecting the queueing service into your listener you can simply push your jobs directly into your queue.

Design for a special WCF service

I need to implement a WCF service which in turn calls a third party web service for some XML result.The client calls come from windows WF apps & will be on separate processes.But for client calls coming from the same parentID, there should be only one call per ParentID, i will explain,
MainID1\SubID1 & MainID1\SubID1 on different processes calls the WCF service for result & if MainID1\SubID1 was the first to make the call, MainID1\SubID2 should wait until the first call is completed.The idea is to prevent unnecessary call to the third party web service, if we get the expected results already from the first call.
But if there are MainID2\SubID1,MainID2\SubID2,MainID2\SubID3 calls, that should be served by a different instance of the WCF service.
In short:
Related requests should be processed sequentially by one instance of WCF service
Unrelated requests should be processed by separate instance
Sorry, if haven't made myself clear, not at the liberty to use the actual business terms(which might have helped to define related & unrelated clients better).
Is this really possible?
Yes, you can do this, but it will not be trivial. Basically you need another component between your WCF Web Service and the 3rd Party service which handles the throttling/locking behavior which you describe. That component needs to create a object for each unique combination and then use that as a lock guard around the outbound call.
Realize that this is clearly multi-threaded development, making it hard to test, and prone to errors if you're not experienced with the ideas around it. You'll want to ensure you're doing double-checked locking whenever you take out a lock.

WCF Service call another service in background

I want to call a web service from another web service in a non-blocking way. I've implemented this by using BackgroundWorker. But, I'm not sure whether this is the best way to do.
Scenario:
I call a web service Service_A which performs certain task & has to inform another web service Service_B about the changes made. I call the Service_B's one-way function NotifyUpdates for handling the updates. Service_A doesn't waits for Service_B's response & continues with its task. The response from the Service_B is logged in the background.
My question is, what is the best way to do it?
Thanks.
BackgroundWorker is purposed for UI use, and I don't think it's the best way to use it here.
If you are using .Net 4 better to use Task
var t = Task.Factory.StartNew(() => DoServiceBCall());
If not,use ThreadPool.QueueUserWorkItem or Thread
ThreadPool.QueueUserWorkItem(new WaitCallback(DoServiceBCall));
Hope this helps
First of all, based on your scenario, if call to Service B is one way, Service A will not receive any response from Service-B except Http Status code (if call to service-B is on Http).
I'd call Service-B asynchronously to keep the things and code simple.
HTH,
Amit

WCF rest client - Post timeout

I am newbie to WCF rest. I have two operation contracts, a POST and GET Method.
In my client, i use HttpWebRequest and try to access the operation contract.
Whenever i access the POST method operation contract i get a timeout error.
But when i try accessing the POST method after a successful GET method, everything works fine.
Is it necessary, that i should use GET method call subsequent to a POST method call?
What wrong am i doing here?
Doing a GET before a POST is not necessary. Your error might not actually be a POST timeout but rather bad data going to the server and the server failing on deserialization.
Is it possible that the GET is setting up some data on the client that travels back to the server? If this is the case then, is it possible for that data that the GET sets to be the data that when unset, makes the POST fail on the server?
The best way to find out is to set tracing on your server. Look here for good examples of WCF tracing.
UPDATE: Another possibility is that your GET code is initializing something on the server side that your POST call is missing. Perhaps a DB connection?

WCF Workflow Service single instance correlation

Using visual studio 2010 RC/.Net 4.0
I have a wcf workflow service with three receive activities defined, basically StartProcessing, StopProcessing, and GetProcessingStatus. This is a long running service that continues to poll an external service for data once StartProcessing is called, until StopProcessing is called.
My problem is with figuring out how to use correlation to ensure that all calls into the service call the same instance of the workflow. I am trying to avoid requiring any sort of instance id be required to be passed back in to subsequent calls to the service. In a nutshell, I would like the workflow being executed to be a singleton, and ensure that all receive activities operate on the same instance. How do I go about doing this?
You can correlate on a constant for example. Edit the XPath in query correlation to return the number 1 for example.
I think that what you want is impossible, you need to correlate, WWF does not know how to execute it. If two parallel calls are received they will use the same object with unexpected results.
In wcf it could be possible, you can set a session in the client or you could manage wcf object creation, but in WWF I think you even don't have that options.