In my Web Api app I'm trying to call other my api application. Applications are hosted locally. The calls are sync and the whole chain looks like this:
Client -[req]-> EchoService -[req]-> EchoService2 -[resp]-> EchoService -[resp]-> Client
Literally these are just echo commands. The problem: when there are 3 or more clients calling the first service in parallel the calls to second service hangs.
Here is the code:
EchoService2:
public class Echo2Controller : ApiController
{
[Route("Echo/{Message}/{RequestID}/{SessionToken}")]
public IHttpActionResult GetEcho(string Message, string RequestID, string SessionToken)
{
EchoResponse response = new EchoResponse();
response.Payload.Message = "Echo 2: " + Message;
response.Success = true;
return Ok(response);
}
}
EchoService:
public class EchoController : ApiController
{
[Route("Echo/{Message}/{RequestID}/{SessionToken}")]
public IHttpActionResult GetEcho(string Message, string RequestID, string SessionToken)
{
EchoResponse response = new EchoResponse();
try
{
string echo2Resp = string.Empty;
using (var client = new WebClient())
{
**// STUCKS HERE WHEN 3 OR MORE CLIENTS**
string sResp = client.DownloadString("http://localhost/api/echoservice2/Echo/" + Message + "/2/3");
EchoResponse echoResponse = JsonConvert.DeserializeObject<EchoResponse>(sResp);
echo2Resp = echoResponse.Payload.Message;
}
response.Payload.Message = "Echo: " + echo2Resp;
response.Success = true;
}
catch(Exception ex)
{
response.Payload.Message = "Echo: Error!";
response.Errors.Add(new Error() { Code = EErrorCodes.GeneralError, Type = EErrorType.Error, Message = ex.Message });
response.Success = false;
}
return Ok(response);
}
}
Client (console app):
{
public int Timeout { get; set; }
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest lWebRequest = base.GetWebRequest(uri);
lWebRequest.Timeout = Timeout;
((HttpWebRequest)lWebRequest).ReadWriteTimeout = Timeout;
return lWebRequest;
}
}
class Program
{
static void Main(string[] args)
{
int tasksCount = 2; // WHEN 2 - works ok, WHEN 3 or more - hangs!**
List<Task> importTasks = new List<Task>();
for(int i = 0; i < tasksCount; ++i)
{
Task importTask = new Task(() => ThreadEcho());
importTasks.Add(importTask);
importTask.Start();
}
Task.WaitAll(importTasks.ToArray());
}
private static void ThreadEcho()
{
int count = 10;
var rnd = new Random(DateTime.Now.Millisecond);
while (count > 0)
{
try
{
string message = Guid.NewGuid().ToString();
string echoResp = string.Empty;
using (var client = new MyWebClient())
{
client.Timeout = 300000;
string sResp = client.DownloadString("http://localhost/api/echoservice/Echo/" + message + "/2/3");
EchoResponse echoResponse = JsonConvert.DeserializeObject<EchoResponse>(sResp);
echoResp = echoResponse.Payload.Message;
}
Console.WriteLine(string.Format("[{0}] [{1}] Request completed: {2} ",
DateTime.Now,
System.Threading.Thread.CurrentThread.ManagedThreadId,
echoResp));
}
catch(Exception ex)
{
Console.WriteLine(string.Format("[{0}] [{1}] Error: {2} ",
DateTime.Now,
System.Threading.Thread.CurrentThread.ManagedThreadId,
ex.Message));
}
--count;
System.Threading.Thread.Sleep(rnd.Next(100, 500));
}
}
}
Tried to trace in VisualStudio but so far what I've found is that EchoService2 controller (last in the chain) never hit. And even an application constructor is not called.
In IIS log file there is no errors except couple of times I've seen codes "- 500 0 64". Also there are no errors in EventLog.
I believe that number 3 is just coincident and the root cause of the problem in something else (something went blocked at IIS side?).
I'm stuck, run out of ideas and any help or hints how to trace what's happening inside IIS will be highly appreciated!