What is the best strategy to defend against an unstable connection that can cause interruptions in our program? Suppose we have to read information from a page, but for reasons of coverage, of the web page itself, or others, we cannot guarantee the uninterruptibility of the service. In these cases, would it be appropriate to use a recursive function? For example, a recursive version of:
import requests, time
def conectar_al_servidor(enlace):
modus = requests.get(enlace)
assert modus.status_code == 200
return modus
def main(enlace='https://www.enlace.com/', segundos=0.5, ciclos):
mento = 0
try:
mento = conectar_al_servidor(enlace)
except AssertionError:
time.sleep(segundos)
try:
mento = conectar_al_servidor(enlace)
except AssertionError:
time.sleep(segundos)
try:
mento = conectar_al_servidor(enlace)
except AssertionError:
#y así sucesivamente hasta llegar a 'n' ciclos, y en ese momento:
except AssertionError:
print("No se puede conectar con el servidor después de", ciclos,"intentos. Se finalizará el programa.")
quit()
if mento != 0:
#Se ha recuperado la conexión con el servidor, ahora vamos a procesar la información que hemos obtenido:
return(procesar(mento, arg0=0, arg1=[1], arg2={2} ... argn='n'))
If you know of any other more efficient way to stop the program and resume it once the connection is back, I'll of course keep that in mind.
The code you put in the question is not recursive. Recursion implies that a function calls itself (or calls another function which calls the first one, etc.)
Any recursive solution to a problem can also be considered as iterative, that is, through some kind of loop.
Generally the iterative version is usually more efficient, and does not incur the problem that recursion can exhaust the stack (for example, in python, there is a maximum of 1000 nested function calls. If a function calls itself more than 1000 times, without returning yet in any of them, the recursion stack is exhausted and the program breaks). A loop is not subject to this restriction, and can be executed many more times.
The code you show, as I said, is not recursive since the function
conectar_al_servidor()
does not contain calls toconectar_al_servidor()
, nor tomain()
. But you don't need it at all.I understand that what you want is to make a function that detects a malfunction in that server and repeats the request, a certain number of times indicated in the variable
ciclos
. For that I don't see why you would have to nest thetry
/ blocks as you have doneexcept
. A single block inside a loop with a counter that detects how many times you have repeated the attempt is enough. Something like that:improvements
The time between retries is generally increased (this is called an exponential backoff ), to avoid saturating the server. For example, it could be duplicated between retries:
On the other hand, the exception you generate is not the most indicated. Assertions should not be used to test for conditions that might normally occur during program execution (such as a server returning an error). They should be reserved only to verify conditions that must always be true , and if they were not, that would indicate that the program is badly done. I mean, rarely.
I recommend you raise another type of exception, such as
ValueError
, or create your own. The following code shows how to create an exception calledServerError
for example:I would also use the parameter
timeout=
,requests.get()
because if the server does not respond, it will take a long time (several minutes) to detect it. You can give it a lower value. If the server has not responded within that time, itrequests.get()
will throw the exceptionTimeOutError
. Sincemain()
you could catch both exceptions like so: