I'm writing a Slack slash Command handler and I noticed that my responses don't get forwarded if they don't fit in the timeout of about five seconds.
How could I wrap my Django view with a function that would detect if we're about to hit the timeout and if that's the case, terminate the connection with a specific response?
Related
I have a request that lasts more than 3 minutes, I want the request to be sent and immediately give the answer 200 and after the end of the work - give the result
The workflow you've described is called asynchronous task execution.
The main idea is to remove time or resource consuming parts of work from the code that handles HTTP requests and deligate it to some kind of worker. The worker might be a diffrent thread or process or even a separate service that runs on a different server.
This makes your application more responsive, as the users gets the HTTP response much quicker. Also, with this approach you can display such UI-friendly things as progress bars and status marks for the task, create retrial policies if task failes etc.
Example workflow:
user makes HTTP request initiating the task
the server creates the task, adds it to the queue and returns the HTTP response with task_id immediately
the front-end code starts ajax polling to get the results of the task passing task_id
the server handles polling HTTP requests and gets status information for this task_id. It returns the info (whether results or "still waiting") with the HTTP response
the front-end displays spinner if server returns "still waiting" or the results if they are ready
The most popular way to do this in Django is using the celery disctributed task queue.
Suppose a request comes, you will have to verify it. Then send response and use a mechanism to complete the request in the background. You will have to be clear that the request can be completed. You can use pipelining, where you put every task into pipeline, Django-Celery is an option but don't use it unless required. Find easy way to resolve the issue
I'm running Django 4.0.5 + Django Rest Framework + Nginx + Gunicorn
Sometimes, I'm going to need to handle some POST requests with a lot of data to process.
The user will wait for a "ok" or "fail" response and a list of ids resulting from the process.
Everything works fine so far for mid size body requests (this is subjective), but when I get into big ones, the process will take 1min+.
It's in these cases when I get a 500 error response from DRF, but my process in the background will keep running till the end (but user will not know it finished successfully).
I was doing some investigation and changed the Gunicorn timeout parameter (to 180), but didn't change the behavior in the service.
Is there a way to set a timeout larger than 60s at the #api_view or somewhere else?
Use celery async tasks to process such requests as background tasks.
I have a Python 3.7 Cloud Function that is triggered via HTTP request.
Function execution can take up to several seconds (2-5).
In some cases, the HTTP request is sent using Javascript from the website's front end.
My questions is, will the Cloud Function finish it's execution normally even if the browser window (that triggered the HTTP request using JS) is closed or user navigates to another page. The function returns "ok" but in that case it doesn't have a destination where to return it.
The function code doesn't do anything differently based on what happens to the client after the request is sent. In fact, it is not even possible to try to cancel the function's execution after the request has been sent.
Closing the connection doesn't affect the outcome from the function's point of view. If a client closes the connection before the response is received, it will just not receive any response generated by the function, so you can not be certain if the client acted on any information returned by the function.
I have several scheduled tasks that essentially perform the same type of functionality:
Request JSON data from an external API
Parse the data
Save the data to a database
The "Timeout (in seconds)" field in the Scheduled Task form is empty for each task.
Each CFM template has the following line of code at the top of the page:
<cfscript>
setting requesttimeout=299;
</cfscript>
However, I consistently see the following entries in the scheduled.log file:
"Information","DefaultQuartzScheduler_Worker-8","04/24/19","12:23:00",,"Task
default - Data - Import triggered."
"Error","DefaultQuartzScheduler_Worker-8","04/24/19","12:24:00",,"The
request has exceeded the allowable time limit Tag: cfhttp "
Notice, there is only a 1-minute difference between the start of the task, and its timing out.
I know that, according to Charlie Arehart, the timeout error messages that are logged are usually not indicative of the actual cause/point of the timeout, and, in fact, I have run tests and confirmed that the CFHTTP calls generally run in a matter of 1-10 seconds.
Lastly, when I make the same request in a browser, it runs until the requesttimeout set in the CFM page is reached.
This leads me to believe that there is some "forced"/"built-in"/"unalterable" request timeout for Scheduled Tasks, or, that it is using the default timeout value for the server and/or application (which is set to 60 seconds for this server/application) yet, I cannot find this documented anywhere.
If this is the case, is it possible to scheduled a task in ColdFusion that runs longer than the forced request timeout?
I'm trying to create one session and reuse it for every request.
The problem is if I try to send a request after 30 seconds after the session was createad, I get:
Caused by: java.nio.channels.ClosedChannelException
at org.eclipse.jetty.http2.HTTP2Session$ControlEntry.succeeded
(HTTP2Session.java:1224) ~[http2-common-9.4.0.v20161208.jar:9.4.0.v20161208]
I tried like this
SSLSessionContext clientSessionContext = sslContextFactory.getSslContext().getClientSessionContext();
clientSessionContext.setSessionTimeout(60000);
but it doesen't seems to work
If you are using HttpClient, the client idle timeout can be set with HttpClient.setIdleTimeout(long).
If you are using the low-level HTTP2Client, the client idle timeout can be set with HTTP2Client.setIdleTimeout(long).
Both will control the connection/session idle timeout, which is apparently what you want. A negative value will disable the idle timeout.