I have two applications WCF client and WCF server running on same machine. Client calls on server for image data, server prepares few images and gives those images to client and client displays them.
Client application make calls to server every 1sec. The image data here is about 10MB in size.
Following is my configuration.
transferMode="Buffered" maxBufferPoolSize="0"
maxReceivedMessageSize="10485760" maxBufferSize="1048576"
binding="netTcpBinding".
Problem: Some times GetImage call taking more time (>6sec).
Below is log info, for CallNumber 151 it is taken more then 6sec.
CallNumber=144, GetImage duration=977
CallNumber=145, GetImage duration=1060
CallNumber=146, GetImage duration=978
CallNumber=147, GetImage duration=1016
CallNumber=148, GetImage duration=1012
CallNumber=149, GetImage duration=1026
CallNumber=150, GetImage duration=1004
CallNumber=151, GetImage duration=6038
CallNumber=152, GetImage duration=954
CallNumber=153, GetImage duration=1046
CallNumber=154, GetImage duration=992
This behavior is very random. In this example above it ran up to 151 calls, some times it is very early and very frequent.
Related
I have a google cloud function that's seems to timeout after being inactive for a certain amount of time or if I re-deploy it. Subsequent calls to the end point work just fine, it's just the initial invocation which doesn't work. The following is an over simplified version of what my cloud function is. I basically use an express app as a handler. Perhaps the issue is with the express app not running the first time around, but running on subsequent invocations?
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors())
app.get('/health', (req, res) => {
res.send('OK');
});
module.exports = app;
Currently have out set to 60s, and a route like the health route shouldn't take that long.
Some interesting log entries
"Function execution took 60004 ms, finished with status: 'timeout'"
textPayload: "Error: Retry total timeout exceeded before any response was received
at repeat (/srv/functions/node_modules/google-gax/build/src/normalCalls/retries.js:80:31)
at Timeout.setTimeout [as _onTimeout] (/srv/functions/node_modules/google-gax/build/src/normalCalls/retries.js:113:25)
at ontimeout (timers.js:436:11)
at tryOnTimeout (timers.js:300:5)
at listOnTimeout (timers.js:263:5)
at Timer.processTimers (timers.js:223:10)"
Cloud Function execution time is limited by the timeout duration, which you can specify at function deployment time. By default, a function times out after 1 minute.
As it is stated in the official documentation:
When function execution exceeds the timeout, an error status is immediately returned to the caller. CPU resources used by the timed-out function instance are throttled and request processing may be immediately paused. Paused work may or may not proceed on subsequent requests, which can cause unexpected side effects.
Note that this period can be extended up to 9 minutes. In order to set the functions timeout limit you can use this gcloud command:
gcloud functions deploy FUNCTION_NAME --timeout=TIMEOUT FLAGS...
More details about your options could be found over here.
But, maybe if your code takes a long time to execute, you may also consider using another serverless option, like Cloud Run.
A Google Cloud Function can be thought of as the event handler for an incoming event request. A cloud function can be triggered from a REST request, pub/sub or cloud storage. For a REST request, consider the function that you supply as the one and only "handler" that the function offers.
The code that you supply (assuming Node.JS) is a function that is passedin an express request object and response object. In the body of the function, you are responsible for handling the request.
Specifically, your Cloud Function should not set up express or attempt to otherwise modify the environment. The Cloud Function provides the environment to be called externally and you provide the logic to be called. Everything else (scaling etc) is handled by Google.
I've been using MVC since version 2, and lately I have come across a project where all of the controller actions are 'async', returning Tasks, and I am trying to understand why somebody would do this.
The View Model for each view is built via an async call to an API. I understand that in order to use the await keyword one must use an async method (and return a Task), but surely without the View Model then the view will fail. There is no choice but to wait for the API to build my View Model.
public async Task<ActionResult> MyCar()
{
return View(await MyAPI.BuildMyCarViewModel());
}
For what reason would controller actions need to be asynchronous?
Let's assume that your part of code
MyAPI.BuildMyCarViewModel()
needs for execution 15 seconds. Then let's assume, that you have 10 000 users, which in range of 2 seconds decided to load some model. And then assume that you don't use caching ( for the sake of example ).
IIS by default has pool of threads 5000.
In described case application pool of IIS will be busy with 5000 threads which will translate into awaiting of your 5000 users for 5 seconds, and other 5000 users will wait until code finish executing. But with async/await .Net will generate state machine, and threads will be executed till moment of awaiting, and then threads will be released for making another useful job. And as soon as
MyAPI.BuildMyCarViewModel()
will return results, other threads or the same threads will return you result. And as outcome application pool of IIS will not be exhausted quickly for long running tasks and your users will receive response much faster, then without usage await/async. If to put simply, await/async gives you possibility to avoid thread pool exhausting quickly for long running fragments of code.
I have an MSDN article on the topic of async ASP.NET. In summary, the benefit is that the request does not take up a thread for the duration of the request. This allows your web app to scale if your backend can scale.
Okay,
Here I have an MVC 4 application and I am trying to create an Asynchronous ActionResult with in that.
Objective : User has a download PDF Icon on the WebPage, and downloading takes much of time. So while server is busy generating the PDF, the user shall be able to perform some actions in webpage.
(clicking "download PDF" link is sending and ajax request to the server, server is fetching some data and is pushing back the PDF)
What is happening is while I call the ajax to download the PDF it starts the process, but blocks every request until and unless it returns back to the browser. That is simple blocking request.
What I have tried so far.
1) Used AsyncController as a base class of controller.
2) Made the ActionResult to an async Task DownloadPDF(), and here I wrapped the whole code/logic to generate PDF into a wrapper. This wrapper is eventually an awaitable thing inside DownloadPDF()
something like this.
public async Task<ActionResult> DownloadPDF()
{
string filepath = await CreatePDF();
//create a file stream and return it as ActionResult
}
private async Task<string> CreatePDF()
{
// creates the PDF and returns the path as a string
return filePath;
}
YES, the Operations are session based.
Am I missing some thing some where?
Objective : User has a download PDF Icon on the WebPage, and downloading takes much of time. So while server is busy generating the PDF, the user shall be able to perform some actions in webpage.
async will not do this. As I describe in my MSDN article, async yields to the ASP.NET runtime, not the client browser. This only makes sense; async can't change the HTTP protocol (as I mention on my blog).
However, though async cannot do this, AJAX can.
What is happening is while I call the ajax to download the PDF it starts the process, but blocks every request until and unless it returns back to the browser. That is simple blocking request.
AFAIK, the request code you posted is completely asynchronous. It is returning the thread to the ASP.NET thread pool while the PDF is being created. However, there are several other aspects to concurrent requests. In particular, one common hangup is that by default the ASP.NET session state cannot be shared between multiple requests.
1) Used AsyncController as a base class of controller.
This is unnecessary. Modern controllers inspect the return type of their actions to determine whether they are asynchronous.
YES, the Operations are session based.
It sounds to me like the ASP.NET session is what is limiting your requests. See Concurrent Requests and Session State. You'll have to either turn it off or make it read-only in order to have concurrent requests within the same session.
I am trying to write a control panel to
Inform about certain KPIS
Enable the user to init certain requests / jobs by pressing a button that then runs a stored proc on the DB or sets a specific setting etc
So far, so good, except I would like to run some bigger jobs where the length of time that the job is running for is unknown and could run over both the script timeout period AND the time the user is willing to wait for a response.
What I want is a "fire and forget" process so the user hits the button and even if they kill the page or turn off their phone they know the job has been initiated and WILL complete.
I was looking into C# BeginExecuteNonQuery which is an async call to the query so the proc is fired but the control doesn't have to wait for a response from it to carry on. However I don't know what happens when the page/app that fired it is shut.
Also I was thinking of some sort of Ajax command that fires the code in a page behind the scenes so the user doesn't know about it running but then again I believe if the user shuts the page down the script will die and the command will die on the server as well.
The only way for certain I know of is a "queue" table where jobs are inserted into this table then an MS Agent job comes along every minute or two checking for new inserts and then runs the code if there is any. That way it is all on the DB and only a DB crash will destroy it. It won't help with multiple jobs waiting to be run concurrently that both take a long time but it's the only thing I can be sure of that will ensure the code is run at all.
Any ideas?
Any language is okay.
Since web browsers are unconnected, requests from them always take the full amount of time. The governing factor isn't what the browser does, but how long the web site itself will allow an action to continue.
IIS (and in general, web servers) have a timeout period for requests, where if the work being done takes simply too long, the request is terminated. This would involve abruptly stopping whatever is taking so long, such as a database call, running code, and so on.
Simply making your long-running actions asynchronous may seem like a good idea, however I would recommend against that. The reason is that in ASP and ASP.Net, asynchronously-called code still consumes a thread in a way that blocks other legitimate request from getting through (in some cases you can end up consuming two threads!). This could have performance implications in non-obvious ways. It's better to just increase the timeout and allow the synchronously blocking task to complete. There's nothing special you have to do to make such a request complete fully, it will occur even if the sender closes his browser or turns off his phone immediately after (presuming the entire request was received).
If you're still concerned about making certain work finish, no matter what is going on with the web request, then it's probably better to create an out-of-process server/service that does the work and to which such tasks can be handed off. Your web site then invokes a method that, inside the service, starts its own async thread to do the work and then immediately returns. Perhaps it also returns a request ID, so that the web page can check on the status of the requested work later through other methods.
You may use asynchronous method and call the query from this method.
Your simple method can be changed in to a asynch method in the following manner.
Consider that you have a Test method to be called asynchronously -
Class AsynchDemo
{
public string TestMethod(out int threadId)
{
//call your query here
}
//create a asynch handler delegate:
public delegate string AsyncMethodCaller(out int threadId);
}
In your main program /or where you have to call the Test Method:
public static void Main()
{
// The asynchronous method puts the thread id here.
int threadId;
// Create an instance of the test class.
AsyncDemo ad = new AsyncDemo();
// Create the delegate.
AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
// Initiate the asychronous call.
IAsyncResult result = caller.BeginInvoke(
out threadId, null, null);
// Call EndInvoke to wait for the asynchronous call to complete,
// and to retrieve the results.
string returnValue = caller.EndInvoke(out threadId, result);
Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
threadId, returnValue);
}
From my experience a Classic ASP or ASP.NET page will run until complete, even if the client disconnects, unless you have something in place for checking that the client is still connected and do something if they are not, or a timeout is reached.
However, it would probably be better practice to run these sorts of jobs as scheduled tasks.
On submitting your web page could record in a database that the task needs to be run and then when the scheduled task runs it checks for this and starts the job.
Many web hosts and/or web control panels allow you to create scheduled tasks that call a URL on schedule.
Alternately if you have direct access to the web server you could create a scheduled task on the server to call a URL on schedule.
Or, if ASP.NET, you can put some code in global.asax to run on a schedule. Be aware though, if your website is set to stop after a certain period of inactivity then this will not work unlesss there is frequent continuous activity.
I have a prototype that works well with SSE and WebSockets, but crashes when using LongPolling in the moment that I put a little bit of stress in the browser.
My app can create games, and each game generate its own events, and those events must be sent to the browser. I have a button to create one, ten and a hundred games at once. Create each game requires a POST call to a WebAPI, so the x10 button creates 10 requests and x100 creates 100 requests to the server.
When I use SSE or WS, it works nicely, I can call the x100 button and create a hundred games, all the games gets its respective events. I can see the 100 HTTP POST request being all successful.
But if I switch to LongPolling mode, I can create games one by one, as long I do not click too fast, and it works well. In the moment I click fast or click the "ten" or "hundred" button, all WebAPI calls but one get stuck and eventually fails with this message:
{"Message":"Anerrorhasoccurred.","ExceptionMessage":"Ataskwascanceled.","ExceptionType":"System.Threading.Tasks.TaskCanceledException","StackTrace":"atSystem.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()\r\n---Endofstacktracefrompreviouslocationwhereexceptionwasthrown---\r\natSystem.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\natSystem.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Tasktask)\r\natSystem.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Tasktask)\r\natSystem.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()"}
Even running in debug, I cannot see that exception happening anywhere.
And SignalR disconnects:
[14:24:37 GMT+0000 (GMT Standard Time)] SignalR: Long poll complete. jquery.signalR-2.0.1.js:75
[14:24:37 GMT+0000 (GMT Standard Time)] SignalR: Disconnect command received from server. jquery.signalR-2.0.1.js:75
[14:24:37 GMT+0000 (GMT Standard Time)] SignalR: Stopping connection.
And it is true, the server actually sends a D:1 in the last response, but I don't know why is that happening, I have nothing in my code that disconnects SignalR connections.
It happens in, at least, Google Chrome and IE 10.
I have no clue about what could be the problem. Any idea?
Cheers.
UPDATE:
I have created a small project that reproduces the issue. It have shared it here.
Accessing: http://localhost/LongPollingLoadTest/ we can add one game, ten or a hundred without problems, because it will use SSE or WebSockets if available.
Now, open http://localhost/LongPollingLoadTest/?transport=longPolling. You will see how most of calls gets stuck and also most of the times, the SignalR connection crashes.
I think the problem is somehow related with the groups management:
[AcceptVerbs("POST")]
public async Task<GameInfo> Post([FromBody]GameRequest request)
{
var game =new GameInfo() { Id = Guid.NewGuid(), Name = request.Name };
if (_games.TryAdd(game.Id, game))
{
var context = GlobalHost.ConnectionManager.GetConnectionContext<MyPersistentConnection>();
await context.Groups.Add(request.ConnectionId, game.Id.ToString());
await context.Connection.Broadcast(game);
Thread.Sleep(100);
return game;
}
else
throw new ArgumentException("Already exists");
}
In your case looks like the longPolling connection became not alive over DisconnectTimeout (which default value is 30 seconds), then server sent disconnect command to client.
Could you also add SignalR trace in your repro?
Issue already reported here as #dfowler indicated: https://github.com/SignalR/SignalR/issues/2456
Cheers.