Timeout on a function call
You may use the signal package if you are running on UNIX:
In [1]: import signal
# Register an handler for the timeout
In [2]: def handler(signum, frame):
...: print("Forever is over!")
...: raise Exception("end of time")
...:
# This function *may* run for an indetermined time...
In [3]: def loop_forever():
...: import time
...: while 1:
...: print("sec")
...: time.sleep(1)
...:
...:
# Register the signal function handler
In [4]: signal.signal(signal.SIGALRM, handler)
Out[4]: 0
# Define a timeout for your function
In [5]: signal.alarm(10)
Out[5]: 0
In [6]: try:
...: loop_forever()
...: except Exception, exc:
...: print(exc)
....:
sec
sec
sec
sec
sec
sec
sec
sec
Forever is over!
end of time
# Cancel the timer if the function returned before timeout
# (ok, mine won't but yours maybe will :)
In [7]: signal.alarm(0)
Out[7]: 0
10 seconds after the call signal.alarm(10)
, the handler is called. This raises an exception that you can intercept from the regular Python code.
This module doesn't play well with threads (but then, who does?)
Note that since we raise an exception when timeout happens, it may end up caught and ignored inside the function, for example of one such function:
def loop_forever():
while 1:
print('sec')
try:
time.sleep(10)
except:
continue
How to wait for setTimeout before each function call?
Since this question is marked with typescript
I'm going to asume that writing this in Typescript is an option.
You could use async/await
to easily achieve the effect you want while your code maintains a normal look:
var myVar;
async function call(){
await myFunction('normal1', 'heading1', 'message1');
await myFunction('normal2', 'heading2', 'message2');
await myFunction('normal3', 'heading3', 'message3');
}
function timeout(delay: number) {
return new Promise(r => setTimeout(r, delay));
}
async function myFunction(msgType: string, heading: string, message: string) {
console.log(!!document.getElementById("snackbarParent"), document.getElementById('snackbarParent'));
if (document.getElementById("snackbarParent") == null) {
await alertFunc(msgType, heading, message);
}
else {
await timeout(3500);
let parent = document.getElementById('snackbarParent');
parent.parentNode.removeChild(parent);
await alertFunc(msgType, heading, message);
}
}
async function alertFunc(msgType, heading, message) {
let div = document.createElement('div');
div.className = 'snackbarParent';
div.id = "snackbarParent";
div.innerHTML = '<div id="snackbar"><b style="color:' + msgType + '"> ' + heading + ' </b>' + message + '</div>';
document.documentElement.appendChild(div);
// Get the snackbar DIV
let x = document.getElementById("snackbar");
// Add the "show" class to DIV
x.className = "show";
await timeout(3000);
x.className = x.className.replace("show", "");
alert("Should display " + heading + " " + message + " now!");
}
Note: If you don't want typescript, babel also has support for async/await
but you will still need a transpiler.
Note To compile for es5
with async/await
you will need a Priomise
library if promises aren't in the environment, and you can use the flowing tconfig.json:
"compilerOptions": {
"target": "es5",
"lib": [
"es5",
"es2015.promise",
"dom"
]
}
A pure js approach could use an onDone
callback to have a way to notify the caller of when the function really completed. This is better that to add the code directly in alertFunc
as other answers suggest as that will make alertFunc
less reusable:
function call() {
myFunction('normal1', 'heading1', 'message1', function () {
myFunction('normal2', 'heading2', 'message2', function () {
myFunction('normal3', 'heading3', 'message3', function () {
// DOne
});
});
});
}
function myFunction(msgType, heading, message, onDone) {
console.log(!!document.getElementById("snackbarParent"), document.getElementById('snackbarParent'));
if (document.getElementById("snackbarParent") == null) {
alertFunc(msgType, heading, message, onDone);
}
else {
setTimeout(function () {
var parent = document.getElementById('snackbarParent');
parent.parentNode.removeChild(parent);
alertFunc(msgType, heading, message, onDone);
}, 3500);
}
}
function alertFunc(msgType, heading, message, onDone) {
var div = document.createElement('div');
div.className = 'snackbarParent';
div.id = "snackbarParent";
div.innerHTML = '<div id="snackbar"><b style="color:' + msgType + '"> ' + heading + ' </b>' + message + '</div>';
document.documentElement.appendChild(div);
// Get the snackbar DIV
var x = document.getElementById("snackbar");
// Add the "show" class to DIV
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
alert("Should display " + heading + " " + message + " now!");
if (onDone)
onDone();
}, 3000);
}
Generically timeout a function call (without Task/CancellationToken)
I agree with everybody saying that using Tasks is better and CancellationToken, but rewriting all the legacy code in order to comply would be too time consuming.
I actually found a solution to my context problem thanks to Access session data from another thread
So here is my final solution :
Public Function CallWithTimeOut(Of T)(timeOut As Integer, dlg As Func(Of T), Optional ByVal ctx As System.Web.HttpContext = Nothing) As T
Dim ret As T
Dim th As Thread
th = New Thread(New ThreadStart(Sub()
If Not ctx Is Nothing Then
System.Web.HttpContext.Current = ctx
End If
ret = dlg.Invoke()
End Sub))
th.Start()
th.Join(timeOut)
If th.IsAlive Then
th.Abort()
Throw New TimeoutException
End If
Return ret
End Function
Cancel timout / timer if function called again --- debounce function
setTimeout
returns an id you can use to clear that timeout with clearTimeout()
. So you can clear the existing timeout at the beginning of your function.
For example if you keep clicking it will keep restarting -- if you don't click it finishes in 2 seconds:
let timerID;
function setTimer() { console.log("starting/restarting timer") clearTimeout(timerID) timerID = setTimeout(() => { console.log("finished") }, 2000)}
<p onclick="setTimer()">click to start</p>
Making function call stop after given time budget
You can use a subprocess for each function call. The subprocess.run()
method accepts a timeout parameter that is the number of seconds the until the child is killed. From the docs:
The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.
So its necessary to handle TimeoutExpired
exceptions that will be thrown if any of the processes do end up exceeding the timeout limit.
Another option is to use signals to set timers and send a SIGLARM
. This has the advantage of being a little less destructive, since you can modify the called functions to properly handle the signal when it comes, giving them a chance to shutdown cleanly. The downside is that signals can be tricky to program, whereas the subprocess option is a pretty self-contained solution right out of the box.
Setting timeout for c/c++ function call
You can call this function in a new thread, and set a timeout to terminate the thread, it will end this function call.
A POSIX example would be:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
pthread_t tid;
// Your very slow function, it will finish running after 5 seconds, and print Exit message.
// But if we terminate the thread in 3 seconds, Exit message will not print.
void * veryslow(void *arg)
{
fprintf(stdout, "Enter veryslow...\n");
sleep(5);
fprintf(stdout, "Exit veryslow...\n");
return nullptr;
}
void alarm_handler(int a)
{
fprintf(stdout, "Enter alarm_handler...\n");
pthread_cancel(tid); // terminate thread
}
int main()
{
pthread_create(&tid, nullptr, veryslow, nullptr);
signal(SIGALRM, alarm_handler);
alarm(3); // Run alarm_handler after 3 seconds, and terminate thread in it
pthread_join(tid, nullptr); // Wait for thread finish
return 0;
}
function call within setTimeout not executing
That is because these, this inside the callback, does not refer to the object outside.
Try this:
delayFilter() {
let timeout = null;
clearTimeout(timeout);
let self = this;
timeout = setTimeout(function() {
self.filterProducts();
}, 1000);
}
filterProducts() {
//do stuff
}
You can also try the arrow function. The reason can be seen here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords.
delayFilter() {
let timeout = null;
clearTimeout(timeout);
timeout = setTimeout(() => {
this.filterProducts();
}, 1000);
}
filterProducts() {
//do stuff
}
How to callback function in set timeout node js
You must wrap your calls to getData in an anonymous function, e.g. setTimeout(function(){ getData(x, y, …) }, 1000)
.
Related Topics
How to Find Words in a List That Starts With a Certain Letter the User Asked For
How to Use a Module Without Installing It on Your Computer
Convert CSV File to Pipe Delimited File in Python
Pandas: Merging Two Columns into One With Corresponding Values
How to Loop Over Grouped Pandas Dataframe
Hiding Axis Text in Matplotlib Plots
How to Restart Airflow Webserver
Regex to Match Digits and At Most One Space Between Them
Python Strftime - Date Without Leading 0
Pyqt: Getting Widgets to Resize Automatically in a Qdialog
How to Extract Data from Dictionary in the List
Django Model Choice Option as a Multi Select Box
How to Convert a 16-Bit to an 8-Bit Image in Opencv