Issue
I'm making a Calculator and the Code freezes when you try to calculate a high number (like 9⁹⁹⁹⁹⁹⁹) To counter this, I want to set a Timeout and if the calculation takes longer than 3 seconds, the result is just "NAN". the Code snipped where the results are calculated looks like this, but it doesn't work. If the calculation takes longer than 3 seconds, the task is not being canceled.
async def do_calculation(realcalculation, X, Y, A, B, C):
try:
result = str(numerize(sympy.sympify(realcalculation).subs(dict(X=X, Y=Y, A=A, B=B, C=C))))
except:
result = "NAN"
raise
return result
async def calculate(realcalculation, X, Y, A, B, C):
loop = asyncio.get_running_loop()
task = loop.create_task(do_calculation(realcalculation, X, Y, A, B, C))
try:
result = await asyncio.wait_for(task, timeout=3)
except asyncio.TimeoutError:
task.cancel()
result = "NAN"
return result
result = await calculate(realcalculation, X, Y, A, B, C)
Solution
There isn't really a good solution for this. The issue is that really big numbers, those that can't be stored in a regular float, automatically switch over to BigNum math (per PEP 237). While arithmetic with regular floats is a nearly constant time operation, BigNum math usually takes polynomial time. So, math with really big numbers just takes a long time.
The reason you can't cancel your task is that there's no point in do_calculation
where you give asyncio
a chance to cancel it. As the docs put it,
When a task is cancelled,
asyncio.CancelledError
will be raised in the task at the next opportunity.
That "opportunity" would be while you're await
-ing something. Because do_calculation
is never await
-ing for something, it can never be canceled.
To counteract this, I'd just add an upper bound to which numbers can be entered. If the number is too high at the beginning, then just return NaN
. Because no upper bound is assured to keep it under 3 seconds on systems of all specifications, you'll need to experiment with what is best for your machine.
Answered By - Michael M.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.