handle multiple request of REST API - c#

I have create a rest api using api Controller in ASP.NET and performing some task that may take 10 minutes to finish task because user enter the time to finish that task. In this case I think multiple request can't be handle.
I am using this --
public class Controller : ApiController
{
[HttpGet]
[ActionName("APICall")]
public string API()
{
Rest y = new Rest();
return y.APiDATA();
}
}
my question is during performing this task when one more request come then does it create new thread for each request or not? if not then how to handle concurrent request .
Please help me.
I am getting following error when calling url after deploy in IIS
{"Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.NullReferenceException","St‌​ackTrace":" at restapi.service.Rest.synthetic()\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.Ac‌​tionExecutor.<>c__Di‌​splayClass13.b__c(Ob‌​ject instance, Object[] methodParameters)\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult]‌​(Func`1 func, CancellationToken cancellationToken)"}

Each request that comes in will be on a separate thread (Task), but also each request that comes in will be on a new instance of your Controller class. However, you'll find that any client that doesn't get a response back within a small period of time (say 10 seconds, or maybe if you're lucky, 60 seconds), will consider it a timeout.
You probably need to park the processing somewhere else (say in a worker queue, and make sure you have a worker running that can handle it), and give back in your response a token they can use to poll for status. Or some other means of communicating to them when the job is done.

Each Web API request works its own separate thread and so multiple request will work. But you may face time out issue.
Regards
Abdul

Related

C# Web-Api - processing inbound requests 'in order that they are recieved'

I've written a web-api project to act as a bridge/gateway between two sub-systems.
I need to ensure that inbound requests are processed 'in the order that they are received'. I'm not overaly familiar with how web-api works and the concern I have is this:
An inbound request comes in, an operation is kicked off and lasts 30 seconds.
Within 5 seconds of the first request being processed, and second request is received and is immediately also processed.
The reason for the concern is that a user may submit an update to a record which will propagate to the other sub-system. However that user may for whatever reason submit a second request. I need to ensure that the first request is completed first, before the subsequent request is actioned. So when hundres of requests are flooding in, it's just a case of processing on a first come, first served basis.
Does anyone know if web-api sort of works like this already, or what I'd need to do in order to get this behaviour?
You can do this this by using global static flag.
Declare one variable like this
static bool bInProcess = false;
Now, when you receive request set this variable to true and do your process. Once you done with your process set this variable to false; During your process if another request come then check this variable if its true then put current thread in sleep mode for 1 sec and check until its true. OR you can return error that another process is running.
//Sample for loop to Queue 2nd request
while (bInProcess )
{
Thread.Sleep(1000);
}
You have to be very careful in this code. In "WebApiConfig" class add the messagehandler class and write this code in that class. Use this method "config.MessageHandlers.Add". I did it long time ago, so I know it works.

task.factory.startnew thread cancel with another comming request

i have a web service with just one method. the web service is working so simple. here is the part of my web service code:
//submit transaction(s) into the database
Simpay simpay = new Simpay { Account = account, Job = new SystemJob { ID = 0, TypeName = "SimpayHistory" } };
Task.Factory.StartNew<bool>(simpay.AddHistory);
as you can see Im using the Task.Factory.StartNew in order to do the task in another thread. but sometimes something wired happens. lets assume task factory take the thread number 300 and start doing its job. suddenly another request comes and it took the same thread!! so my first task just cancel!!(I'm not sure about it but its the only thing that i found in my logs!)
now i wonder is this possible? how can i avoid this?
here is part of my log file. as you can see another request comes and take the old one thread!!!(first line belong to the Task factory and second one belongs to the new request. thread number is 345)
[DEBUG];[2015-11-05 07:37:57,526];[345];[DataBase.Query line:56];[2.5646];[];[(Stored Procedure: ud_prc_simPayRetrieveLastTransaction)(Code: 1)(Message: No Error.)(SQL Parameters: #mobileNumber)]
[INFO ];[2015-11-05 07:37:57,667];[345];[Identity.DoesUserNameContentValid line:146];[0.0591];[];[(Message: user name content validation completed successfully.)]
What you are experiencing is what Job Skeet describes as re-entrance. I must refer you to his post here. He gives an in depth explanation of it.
A short answer is that it is possible for future executions of tasks to hijack existing ones and kill out their processes.

Payflow API returning null response on multiple asynch requests

I'm using a simple Web API controller to accept a request from a client to process a payment. The Payflow payment request is started in a new task, and I immediately return a status to the client while I wait for the transaction to complete in my task.
However, in testing, if I send two requests back-to-back to my API, the second request will receive a null response from the SubmitTransaction method of the Payflownet API. Why is this happening?
Here is my method which is making the call
private NameValueCollection SubmitTransaction(NameValueCollection pfpParams)
{
string transactionString = GetTransactionString(pfpParams);
string pfpResponse = _pfNetApi.SubmitTransaction(transactionString, PayflowUtility.RequestId);
return HttpUtility.ParseQueryString(pfpResponse);
}
And here is the value of transactionString that I'm passing to the SubmitTransaction method in both cases (dummy credit card info):
ACCT=4111111111111111&EXPDATE=0115&COMMENT1=&COMMENT2=&CVV2=123&NAME=Joshua Dixon&STREET=123 x st&TENDER=C&ZIP=12345&AMT=5.00&TRXTYPE=S&USER=test&PWD=xxxx&PARTNER=Verisign&VENDOR=test
Whenever I send a single request with that string, the response is correct and expected. However, whenever I send two asynchronous requests with that string, if the first hasn't completed, the second response is always null.
OP's co-worker, answering this in case anyone else has this problem.
This seems to be an issue with thread-safety. Though the documentation indicates otherwise, PayflowNETAPI.SubmitTransaction does not seem to be thread-safe. The problem was solved by using a new instance of PayflowNETAPI for each transaction.

Speeding up http web request in WCF invoked method

Hi I am writing a WCF service not hosted on IIS. It runs on my server as console application.
I have a static method that is invoked by the mentioned service.
In this method I have async web request that sends sms.
Sometimes it happens that sms is never recieved. After some debuging I found out that when I remove async call the web request sometimes throws an exception with message: 'The operation has timed out'. This happens when i try to send many smss in short period of time.
But when i type the address of the web request in browser everything works fine. (the times i press refresh, no matter how fast, that number of times i receive sms) how can this be achived with what i've got.
So far i have
public static bool DoTheRequest(string number, string message)
{
try
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(string.Format("http://SomeURL?With={0}&something={1}", number, message));
myReq.BeginGetResponse(FinishWebRequest, myReq);
}
catch (Exception ex)
{
throw ex;
}
return true;
}
static void FinishWebRequest(IAsyncResult result)
{
HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
}
EDIT:
And the service definition:
[OperationContract]
void TestSms(string number);
and implementation:
public void TestSms(string number)
{
Utilities.DoTheRequest(number, "THIS IS A TEST");
}
Please help
Depending on how many times you are calling the send-sms function in a short period of time, I surmise that it's doing it a lot faster than you can refresh in your browser - and you're managing to flood whatever service it is you are using with your SMS calls.
In this scenario, I would suggest that your web-service method actually puts the SMS in to a queue, and some kind of a background worker thread that is designed not to throttle the API that actually sends the SMS, has the job of batching up these SMSs and sending them.
Better yet, to facilitate the issue that machines and software are not perfect, and lightning does indeed strike, I would suggest that you push SMSs in to some kind of back-end data store and leave it at that. A background worker job/thread then has the job of finding all SMSs that are unsent and trying to send them (but sending no more than "x per minute"), each one being marked as "Sent" upon completion.
This has the added advantage that you can throw as many SMSs as you want at your backing data storage, if the machine dies it can pick up where it left off, and if you get some failures, they can be retried.

Detecting async client disconnect in ASP.NET MVC

Given an async controller:
public class MyController : AsyncController
{
[NoAsyncTimeout]
public void MyActionAsync() { ... }
public void MyActionCompleted() { ... }
}
Assume MyActionAsync kicks off a process that takes several minutes. If the user now goes to the MyAction action, the browser will wait with the connection open. If the user closes his browser, the connection is closed. Is it possible to detect when that happens on the server (preferably inside the controller)? If so, how? I've tried overriding OnException but that never fires in this scenario.
Note: I do appreciate the helpful answers below, but the key aspect of this question is that I'm using an AsyncController. This means that the HTTP requests are still open (they are long-lived like COMET or BOSH) which means it's a live socket connection. Why can't the server be notified when this live connection is terminated (i.e. "connection reset by peer", the TCP RST packet)?
I realise this question is old, but it turned up frequently in my search for the same answer.
The details below only apply to .Net 4.5
HttpContext.Response.ClientDisconnectedToken is what you want. That will give you a CancellationToken you can pass to your async/await calls.
public async Task<ActionResult> Index()
{
//The Connected Client 'manages' this token.
//HttpContext.Response.ClientDisconnectedToken.IsCancellationRequested will be set to true if the client disconnects
try
{
using (var client = new System.Net.Http.HttpClient())
{
var url = "http://google.com";
var html = await client.GetAsync(url, HttpContext.Response.ClientDisconnectedToken);
}
}
catch (TaskCanceledException e)
{
//The Client has gone
//you can handle this and the request will keep on being processed, but no one is there to see the resonse
}
return View();
}
You can test the snippet above by putting a breakpoint at the start of the function then closing your browser window.
And another snippet, not directly related to your question but useful all the same...
You can also put a hard limit on the amount of time an action can execute for by using the AsyncTimeout attribute. To use this use add an additional parameter of type CancellationToken. This token will allow ASP.Net to time-out the request if execution takes too long.
[AsyncTimeout(500)] //500ms
public async Task<ActionResult> Index(CancellationToken cancel)
{
//ASP.Net manages the cancel token.
//cancel.IsCancellationRequested will be set to true after 500ms
try
{
using (var client = new System.Net.Http.HttpClient())
{
var url = "http://google.com";
var html = await client.GetAsync(url, cancel);
}
}
catch (TaskCanceledException e)
{
//ASP.Net has killed the request
//Yellow Screen Of Death with System.TimeoutException
//the return View() below wont render
}
return View();
}
You can test this one by putting a breakpoint at the start of the function (thus making the request take more than 500ms when the breakpoint is hit) then letting it run out.
Does not Response.IsClientConnected work fairly well for this? I have just now tried out to in my case cancel large file uploads. By that I mean if a client abort their (in my case Ajax) requests I can see that in my Action. I am not saying it is 100% accurate but my small scale testing shows that the client browser aborts the request, and that the Action gets the correct response from IsClientConnected.
It's just as #Darin says. HTTP is a stateless protocol which means that there are no way (by using HTTP) to detect if the client is still there or not. HTTP 1.0 closes the socket after each request, while HTTP/1.1 can keep it open for a while (a keep alive timeout can be set as a header). That a HTTP/1.1 client closes the socket (or the server for that matter) doesn't mean that the client has gone away, just that the socket hasn't been used for a while.
There are something called COMET servers which are used to let client/server continue to "chat" over HTTP. Search for comet here at SO or on the net, there are several implementations available.
For obvious reasons the server cannot be notified that the client has closed his browser. Or that he went to the toilet :-) What you could do is have the client continuously poll the server with AJAX requests at regular interval (window.setInterval) and if the server detects that it is no longer polled it means the client is no longer there.

Categories

Resources