2

I am currently developing a REST Service where one of the methods is a long running task (named CalculatePrimeOneWay). Its definition is

[OperationContract(IsOneWay = true)]
[WebInvoke(Method = "POST", UriTemplate = "primeoneway/{jobnumber}")]
void CalculatePrimeOneWay(string jobnumber, Prime prime);

As there is no callback capability with a REST Service, I thought about implementing a kind of polling method to obtain status information. This polling method is defined as

    [OperationContract]
    [WebGet(UriTemplate = "poll/{jobnumber}")]
    Job GetJobStatus(string jobnumber);

I write status information into a MS SQL table.

I start my client and invoke the CalculatePrimeOneWay Method. Subsequent calls to GetJobStatus return a WebException with Protocol Error, Status Code 400 and Status Description Bad Request. However, if CalculatePrimeOneWay is finished and I then invoke GetJobStatus, all works perfectly fine.

Why am I unable to call GetJobStatus while CalculatePrimeOneWay is still running? What other solutions would be possible for my scenario of a long runnning task and a polling mechanism?

Thanks

Walter Taus
  • 33
  • 1
  • 7
  • 1
    _"What other solutions would be possible for my scenario of a long runnning task and a polling mechanism?"_ - did you try searching? It's never a good idea to let an HTTP call last longer than a few milliseconds. – CodeCaster Aug 04 '16 at 15:40
  • 1
    I did search the internet and the only potential idea I found was this polling mechanism. Since the long running method is defined as OneWay, the HTTP call itself is finished pretty fast, which I can also see in my log. – Walter Taus Aug 04 '16 at 15:48
  • Are you using per-session/singleton instancing? Or are you re-using the client channel? Or both? – tom redfern Aug 04 '16 at 16:05

1 Answers1

0

The behaviour you're getting may be a result of one or both of two things:

  1. You are running the service with per-session or singleton instancing
  2. You are re-using the same client channel to make the polling call as you did to make the one-way call.

You should have the service configured to per-call instancing and make the polling call on a new client channel instance.

I have now explicitly defined the service PerCall. For each call from the client I get a new HttpWebRequest object and after the call, I close the web response object. The behaviour is still the same

OK try replacing

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

with

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
                 ConcurrencyMode = ConcurrencyMode.Multiple,
                 UseSynchronizationContext = false)]

I am using IIS Express out of my VisualStudio

OK - the reason you are getting this behaviour is because you're hosting using the Visual Studio which uses the cassini web server. This does not support concurrency when processing requests. See posts here and here.

Try hosting the service temporarily in a console app and this problem will be resolved.

Community
  • 1
  • 1
tom redfern
  • 30,562
  • 14
  • 91
  • 126
  • I have now explicitely defined the service PerCall. For each call from the client I get a new HttpWebRequest object and after the call I close the webresponse object. The behavior is still the same. – Walter Taus Aug 05 '16 at 15:45
  • I have defined the ServiceBehavior as stated above. Furthermore, I have split up the service into two completely separate services. One has the OneWay Method in it. On a different port the second Service has the polling function in it. The Result is still the same. The polling only works when the OneWay method has finished its task. When I try to poll during execution of the OneWay method, I get the WebException and also my OneWay method stops working. I am using IIS Express out of my VisualStudio. – Walter Taus Aug 06 '16 at 09:22
  • @WalterTaus this is happening because you are using VS to run this. See edit to my answer. – tom redfern Aug 12 '16 at 08:59