How to use a timeout context inside a timeout context in python
Most solutions for timeout context uses signals. But signals get overwritten and only the last signal handler remains. The consequence is that you cannot use a timeout context if the code is already in a timeout context (that could have been started by you, another developer, a library, a framework, who knows?).
So, basically my over-simplified use-case is this:
with Timeout(1): #A
with Timeout(100): #B
sleep(10) #C
print('Fail')
This code should never print "Fail". But every implementation of Timeout() I've seen so far does the same thing:
- Timeout A starts a timeout context
- Timeout B starts a new timeout context (overwriting the Timeout context from A)
- The timeout never occurs, since the computing in C takes less than 100s
- The execution resumes without timeout context and last more than 1s
The previous example seems a little bit stupid, but the real use case is more like:
with Timeout(30):
for a in list:
with Timeout(10):
heavy_computing(a)
I don't know the length of "list", I don't want to take more than 10s per element of the list and no more than 30s in total.
So my question is: What would be the best implementation of the Timeout() context that doesn't use signal and have support for embeded contexts inside contexts?
Edit:
- The solution doesn't have to be thread-safe, just safe from another Timeout context from an higher level of scope.
- If possible, I'd prefer a solution that is the less invasive possible, as I may use it to call a library that I didn't wrote.
Edit2:
Ok, a little clarification concerning how I consider the Timeout. For me Timeout is a non-intrusive solution to return a partial result (or no result at all) if a black-box operation takes too long. The result must be returned fastly but can be incomplete.
def function(argument):
results =
with Timeout(50):
for a in arguments:
with Timeout(20):
results.append(black_box(a))
return results
If the function takes more than 50s, then the execution is aborted and an incomplet result is returned. And if black_box takes more than 10s, it will be skipped to go on with the next result.
Example:
arguments = [a, b, c, d]
black_box(a) takes 25s and returns w
black_box(b) takes 20s and returns x
black_box(c) takes 5s and returns y
black_box(d) takes 10s and returns z
results = [x, y]
explanations:
a took more than 20s and was skipped
b took 20s more seconds (40s in total) and was computed successfully
c took 5s more seconds (45s in total), still less than 50s
d was aborted because of the 50s timeout
The function blackbox is not aware that it is called from a Timeout context and does not contains timeout specific code.
This code is an exemple and may be a little different. Maybe we need some try.. except to catch timeout errors, etc. But black_box can't be modified.
python timeout
|
show 1 more comment
Most solutions for timeout context uses signals. But signals get overwritten and only the last signal handler remains. The consequence is that you cannot use a timeout context if the code is already in a timeout context (that could have been started by you, another developer, a library, a framework, who knows?).
So, basically my over-simplified use-case is this:
with Timeout(1): #A
with Timeout(100): #B
sleep(10) #C
print('Fail')
This code should never print "Fail". But every implementation of Timeout() I've seen so far does the same thing:
- Timeout A starts a timeout context
- Timeout B starts a new timeout context (overwriting the Timeout context from A)
- The timeout never occurs, since the computing in C takes less than 100s
- The execution resumes without timeout context and last more than 1s
The previous example seems a little bit stupid, but the real use case is more like:
with Timeout(30):
for a in list:
with Timeout(10):
heavy_computing(a)
I don't know the length of "list", I don't want to take more than 10s per element of the list and no more than 30s in total.
So my question is: What would be the best implementation of the Timeout() context that doesn't use signal and have support for embeded contexts inside contexts?
Edit:
- The solution doesn't have to be thread-safe, just safe from another Timeout context from an higher level of scope.
- If possible, I'd prefer a solution that is the less invasive possible, as I may use it to call a library that I didn't wrote.
Edit2:
Ok, a little clarification concerning how I consider the Timeout. For me Timeout is a non-intrusive solution to return a partial result (or no result at all) if a black-box operation takes too long. The result must be returned fastly but can be incomplete.
def function(argument):
results =
with Timeout(50):
for a in arguments:
with Timeout(20):
results.append(black_box(a))
return results
If the function takes more than 50s, then the execution is aborted and an incomplet result is returned. And if black_box takes more than 10s, it will be skipped to go on with the next result.
Example:
arguments = [a, b, c, d]
black_box(a) takes 25s and returns w
black_box(b) takes 20s and returns x
black_box(c) takes 5s and returns y
black_box(d) takes 10s and returns z
results = [x, y]
explanations:
a took more than 20s and was skipped
b took 20s more seconds (40s in total) and was computed successfully
c took 5s more seconds (45s in total), still less than 50s
d was aborted because of the 50s timeout
The function blackbox is not aware that it is called from a Timeout context and does not contains timeout specific code.
This code is an exemple and may be a little different. Maybe we need some try.. except to catch timeout errors, etc. But black_box can't be modified.
python timeout
You can try a decorative approach. Based on @user2357112's comment it should be thread safe.
– Idlehands
Nov 15 '18 at 14:39
Possible duplicate of Python timeout context manager with threads
– Idlehands
Nov 15 '18 at 20:16
@Idlehands This thread shows the solution for a timer that prints execution time, not a timeout context that stops code execution if it takes too long.
– Matthieu
Nov 16 '18 at 10:18
@Idlehands Mr Fooz' response could work but is very intrusive. And this link is aboat thread-safe timeouts, my application is mono-threaded, but have a different problem: I'd like to set multiple granularity of timeouts that don't overwrite each other.
– Matthieu
Nov 16 '18 at 10:35
Yes my confusion of the first thread came upon me thus why I linked the second one after. What is the definition of yourTimeout
right now?
– Idlehands
Nov 16 '18 at 14:00
|
show 1 more comment
Most solutions for timeout context uses signals. But signals get overwritten and only the last signal handler remains. The consequence is that you cannot use a timeout context if the code is already in a timeout context (that could have been started by you, another developer, a library, a framework, who knows?).
So, basically my over-simplified use-case is this:
with Timeout(1): #A
with Timeout(100): #B
sleep(10) #C
print('Fail')
This code should never print "Fail". But every implementation of Timeout() I've seen so far does the same thing:
- Timeout A starts a timeout context
- Timeout B starts a new timeout context (overwriting the Timeout context from A)
- The timeout never occurs, since the computing in C takes less than 100s
- The execution resumes without timeout context and last more than 1s
The previous example seems a little bit stupid, but the real use case is more like:
with Timeout(30):
for a in list:
with Timeout(10):
heavy_computing(a)
I don't know the length of "list", I don't want to take more than 10s per element of the list and no more than 30s in total.
So my question is: What would be the best implementation of the Timeout() context that doesn't use signal and have support for embeded contexts inside contexts?
Edit:
- The solution doesn't have to be thread-safe, just safe from another Timeout context from an higher level of scope.
- If possible, I'd prefer a solution that is the less invasive possible, as I may use it to call a library that I didn't wrote.
Edit2:
Ok, a little clarification concerning how I consider the Timeout. For me Timeout is a non-intrusive solution to return a partial result (or no result at all) if a black-box operation takes too long. The result must be returned fastly but can be incomplete.
def function(argument):
results =
with Timeout(50):
for a in arguments:
with Timeout(20):
results.append(black_box(a))
return results
If the function takes more than 50s, then the execution is aborted and an incomplet result is returned. And if black_box takes more than 10s, it will be skipped to go on with the next result.
Example:
arguments = [a, b, c, d]
black_box(a) takes 25s and returns w
black_box(b) takes 20s and returns x
black_box(c) takes 5s and returns y
black_box(d) takes 10s and returns z
results = [x, y]
explanations:
a took more than 20s and was skipped
b took 20s more seconds (40s in total) and was computed successfully
c took 5s more seconds (45s in total), still less than 50s
d was aborted because of the 50s timeout
The function blackbox is not aware that it is called from a Timeout context and does not contains timeout specific code.
This code is an exemple and may be a little different. Maybe we need some try.. except to catch timeout errors, etc. But black_box can't be modified.
python timeout
Most solutions for timeout context uses signals. But signals get overwritten and only the last signal handler remains. The consequence is that you cannot use a timeout context if the code is already in a timeout context (that could have been started by you, another developer, a library, a framework, who knows?).
So, basically my over-simplified use-case is this:
with Timeout(1): #A
with Timeout(100): #B
sleep(10) #C
print('Fail')
This code should never print "Fail". But every implementation of Timeout() I've seen so far does the same thing:
- Timeout A starts a timeout context
- Timeout B starts a new timeout context (overwriting the Timeout context from A)
- The timeout never occurs, since the computing in C takes less than 100s
- The execution resumes without timeout context and last more than 1s
The previous example seems a little bit stupid, but the real use case is more like:
with Timeout(30):
for a in list:
with Timeout(10):
heavy_computing(a)
I don't know the length of "list", I don't want to take more than 10s per element of the list and no more than 30s in total.
So my question is: What would be the best implementation of the Timeout() context that doesn't use signal and have support for embeded contexts inside contexts?
Edit:
- The solution doesn't have to be thread-safe, just safe from another Timeout context from an higher level of scope.
- If possible, I'd prefer a solution that is the less invasive possible, as I may use it to call a library that I didn't wrote.
Edit2:
Ok, a little clarification concerning how I consider the Timeout. For me Timeout is a non-intrusive solution to return a partial result (or no result at all) if a black-box operation takes too long. The result must be returned fastly but can be incomplete.
def function(argument):
results =
with Timeout(50):
for a in arguments:
with Timeout(20):
results.append(black_box(a))
return results
If the function takes more than 50s, then the execution is aborted and an incomplet result is returned. And if black_box takes more than 10s, it will be skipped to go on with the next result.
Example:
arguments = [a, b, c, d]
black_box(a) takes 25s and returns w
black_box(b) takes 20s and returns x
black_box(c) takes 5s and returns y
black_box(d) takes 10s and returns z
results = [x, y]
explanations:
a took more than 20s and was skipped
b took 20s more seconds (40s in total) and was computed successfully
c took 5s more seconds (45s in total), still less than 50s
d was aborted because of the 50s timeout
The function blackbox is not aware that it is called from a Timeout context and does not contains timeout specific code.
This code is an exemple and may be a little different. Maybe we need some try.. except to catch timeout errors, etc. But black_box can't be modified.
python timeout
python timeout
edited Nov 19 '18 at 23:17
Matthieu
asked Nov 15 '18 at 14:12
MatthieuMatthieu
105
105
You can try a decorative approach. Based on @user2357112's comment it should be thread safe.
– Idlehands
Nov 15 '18 at 14:39
Possible duplicate of Python timeout context manager with threads
– Idlehands
Nov 15 '18 at 20:16
@Idlehands This thread shows the solution for a timer that prints execution time, not a timeout context that stops code execution if it takes too long.
– Matthieu
Nov 16 '18 at 10:18
@Idlehands Mr Fooz' response could work but is very intrusive. And this link is aboat thread-safe timeouts, my application is mono-threaded, but have a different problem: I'd like to set multiple granularity of timeouts that don't overwrite each other.
– Matthieu
Nov 16 '18 at 10:35
Yes my confusion of the first thread came upon me thus why I linked the second one after. What is the definition of yourTimeout
right now?
– Idlehands
Nov 16 '18 at 14:00
|
show 1 more comment
You can try a decorative approach. Based on @user2357112's comment it should be thread safe.
– Idlehands
Nov 15 '18 at 14:39
Possible duplicate of Python timeout context manager with threads
– Idlehands
Nov 15 '18 at 20:16
@Idlehands This thread shows the solution for a timer that prints execution time, not a timeout context that stops code execution if it takes too long.
– Matthieu
Nov 16 '18 at 10:18
@Idlehands Mr Fooz' response could work but is very intrusive. And this link is aboat thread-safe timeouts, my application is mono-threaded, but have a different problem: I'd like to set multiple granularity of timeouts that don't overwrite each other.
– Matthieu
Nov 16 '18 at 10:35
Yes my confusion of the first thread came upon me thus why I linked the second one after. What is the definition of yourTimeout
right now?
– Idlehands
Nov 16 '18 at 14:00
You can try a decorative approach. Based on @user2357112's comment it should be thread safe.
– Idlehands
Nov 15 '18 at 14:39
You can try a decorative approach. Based on @user2357112's comment it should be thread safe.
– Idlehands
Nov 15 '18 at 14:39
Possible duplicate of Python timeout context manager with threads
– Idlehands
Nov 15 '18 at 20:16
Possible duplicate of Python timeout context manager with threads
– Idlehands
Nov 15 '18 at 20:16
@Idlehands This thread shows the solution for a timer that prints execution time, not a timeout context that stops code execution if it takes too long.
– Matthieu
Nov 16 '18 at 10:18
@Idlehands This thread shows the solution for a timer that prints execution time, not a timeout context that stops code execution if it takes too long.
– Matthieu
Nov 16 '18 at 10:18
@Idlehands Mr Fooz' response could work but is very intrusive. And this link is aboat thread-safe timeouts, my application is mono-threaded, but have a different problem: I'd like to set multiple granularity of timeouts that don't overwrite each other.
– Matthieu
Nov 16 '18 at 10:35
@Idlehands Mr Fooz' response could work but is very intrusive. And this link is aboat thread-safe timeouts, my application is mono-threaded, but have a different problem: I'd like to set multiple granularity of timeouts that don't overwrite each other.
– Matthieu
Nov 16 '18 at 10:35
Yes my confusion of the first thread came upon me thus why I linked the second one after. What is the definition of your
Timeout
right now?– Idlehands
Nov 16 '18 at 14:00
Yes my confusion of the first thread came upon me thus why I linked the second one after. What is the definition of your
Timeout
right now?– Idlehands
Nov 16 '18 at 14:00
|
show 1 more comment
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53321344%2fhow-to-use-a-timeout-context-inside-a-timeout-context-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53321344%2fhow-to-use-a-timeout-context-inside-a-timeout-context-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You can try a decorative approach. Based on @user2357112's comment it should be thread safe.
– Idlehands
Nov 15 '18 at 14:39
Possible duplicate of Python timeout context manager with threads
– Idlehands
Nov 15 '18 at 20:16
@Idlehands This thread shows the solution for a timer that prints execution time, not a timeout context that stops code execution if it takes too long.
– Matthieu
Nov 16 '18 at 10:18
@Idlehands Mr Fooz' response could work but is very intrusive. And this link is aboat thread-safe timeouts, my application is mono-threaded, but have a different problem: I'd like to set multiple granularity of timeouts that don't overwrite each other.
– Matthieu
Nov 16 '18 at 10:35
Yes my confusion of the first thread came upon me thus why I linked the second one after. What is the definition of your
Timeout
right now?– Idlehands
Nov 16 '18 at 14:00