I'm trying to implement an API that performs some really lengthy tasks using a Web Service. I basically want the Web Service to kick off a thread that performs the lengthy task and leaves it running until it completes. The issue is because its an API I want it to be cross-platform. So my questions are the following:
- Is it possible to make asynchronous calls that do not require the client to be on .NET Framework? (It seems the Begin/End framework in place requires I return the .NET IASyncResult object) If so how can this be done? Totally unambiguous sample code would be amazingly helpful.
- Because there is no state preservation in a web service, can this thread be later recovered? In the event that the client wants to cancel the process this would be highly important.
Expose a REST API to your clients. Then, you just need a layer of code that translates between your .NET asynchronous objects and the REST service.
You can expose a REST method that returns status of the operation, and another REST method that cancels your async operation.
For long running operations, I generally set up a Windows Service with a
ThreadPool
. You can expose your IAsync API there.The easiest way to expose a REST API on an IIS Server is with a simple ASP.NET MVC application. You can execute your long-running asynchronous processes directly from the controller methods.
Okay, back up a second.
If you want people to be able to call asynch, then they control and you just respond. If you want asynch work to be done on your side, then you need to institute a different pattern. One pattern is to set up a method that calls the work and then another method to see the status of the work. The first method returns some type of token/id that can be used to check the status on the other call. You then have a third method to pick up the results. This is all client driven.
You can, in theory, set up a callback mechanism, but the client needs to have a means of getting the answer, which is a service on their side. This is more complex, and less "public API" in nature, but it can work with clients.
The heterogenous nature of the system should not be a factor. And, you can institute both patterns, so clients that have a web service that can take the answer can fire and forget, while others poll.
The one downside of polling is you add more weight to your side, so set proper expectations and be prepared to throttle the guy that does something like this:
If you can get around heterogenous environs (open standards, et al), and can force .NET, you have other options, as Craig has mentioned.
We use AppFabric Workflow services for this.
They're exposed as WCF services, so anything which can make a SOAP call -- or any other supported WCF transport -- can invoke them.
Persistence is included for free (if you set up a SQL Server), as is monitoring and administration, and .NET clients are generated automatically.
One potential downside: You need IIS 7+ and .NET 4.
This is a good place to start:
http://msdn.microsoft.com/en-us/library/aa480516.aspx
If you implement this pattern, from the client perspective, nothing changes. You can implement a second web method to check the status of any running jobs you queue up in your async method.
From the sample code, modified somewhat to give you an idea of what you need to do (I don't expect this would compile):
As far as the client is concerned, they are calling a webmethod called LenghtyProcedure that will not return until the job is complete.