[Tutor] Where does the program pointer go when...

Alan Gauld alan.gauld at yahoo.co.uk
Tue Feb 28 19:44:16 EST 2023


On 28/02/2023 18:26, Dave (NK7Z) wrote:

> I am trying to get my head around what is a timeout, and what happens 
> when one occurs.  

I'll answer this in general terms because  there is no single
definition of how timeouts work or are used.

Basically a timeout just means that an operation is time limited.
It will start and if it does not complete within the specified
time it either returns empty handed or raises an error or
causes some specified handler function to execute.

There are multiple ways to implement timeouts from software
to hardare and from simple clock lookups to multi-threaded
interrupts. So it is impossible to give a single answer to how they
work. The simplest form is a simple loop and timecheck:

In spseudo code:

def timed_op(timeout):
    start = gettime()
    while True:
       time = gettime()
       if time < start+timeout:
          result = do_operation()
          if resultOK(result):
             return result
       else: raise TimeoutError


So we start a timer and then enter an infinite loop.
Every time round we see if the timer has exceeded
the timeout period. If not we carry out the desired
operation. If the operation succeeds (according to
some arbitrary definition of success!) we return
the result. Otherwise we go round the loop again.
If the timeout is exceeded we rraise a timeout error
and the caller must decide what to do  next.

But both OS and hardware usually have special
mechanisms for interrupting a running process
after a given time, so a process can invoke
that feature too. This tends to be the case
with servers and long running processes or tasks
which use the network (or other fallible resources).
In that case the OS will step in and stop the process
and call an interrupt handler function (or signal).
That function will probably just return an error code
to the caller or similar.


> As a result of this effort, I find I have a failed understanding of what 
> happens when a TIMEOUT occurs.  I am fairly sure I don't even know WHAT 
> a TIMEOUT is...  See assumptions list later.

For a specific scenario you have to dig deeper into
how the library in question expects you to proceed.
It may be that you provide a default value, raise an
error (or catch an error from the library!)  or you
may provide the library with an error handlr function
that the library calls in the event of timeout. It
all depends on the library. Good documentation/tutorials
are invaluable here.

> The snippit below is designed to read one line from a telnet stream that 
> never ends, looking for a \n, as the end of a line, while looking to 
> trap errors, and leave me a message as to what failed via 
> logit(logdata). 


>          try:
>              result = tn.read_until(b"\r\n", TIMEOUT)
>              if result == b'':
>                  relogin()
>                  configureCluster()
>                  exitscript()
>          except socket.error:  # If socket error-- exit with error.
>              logdata = 'Socket Error in watchstream(), at main read loop.'
>              logit(logdata)
>              exitscript()
>          except EOFError:
>              failcode = 6
>              logdata = 'EOF at main read loop.'
>              logit(logdata)
>              exitscript()
>          except OSError:
>              logdata = 'OS Error in watchstream().'
>              logit(logdata)
>              exitscript()
> 
> Rest of script...
> 
> I have at least two assumptions I want to check here:
> 
> 1.  TIMEOUT is defined as when when the telnet server just stops 
> spending data, but the telnet connection still exists, and TIMEOUT is 
> exceeded.  i.e. the far side data collection died, but left the server 
> connected to my client.  Is this correct?

No idea. But the telnet module docs say:
=========
Telnet.read_until(expected, timeout=None)
Read until a given byte string, expected, is encountered or until
timeout seconds have passed.

When no match is found, return whatever is available instead, possibly
empty bytes. Raise EOFError if the connection is closed and no cooked
data is available.
==========

So it looks like in this case the timeout causes the function to return
as much data as it has collected so far, regardless of wherther it found
your expected terminator.

Note it also says telnetlib is deprecated and will be removed in 3.13.
You should probably move to another library - maybe ssh based?

> 2.  I assume the run pointer, (where the next instruction is run), just 
> drops down to the "Rest of script..." and the run continues, if TIMEOUT 
> is reached.  Is this correct?

It depends on how the timeout is built.
But in your specific case, yes. You get a return
from the function as normal. The TIMEOUT is purely to prevent
read_until() locking up and never returning.

> I am trying to trap all errors, and recover cleanly from them while not 
> hammering the far side telnet server with login attempts...

Good, but unrelated to timeouts! :-)

> Any help would be appreciated, I am new to Python...  I have looked all 
> over and have not located anything that tells me what a TIMEOUT is 
> exactly.  Is it if the telnet server drops, is it if the data flow 
> stops, but the telnet server is still connected, etc...

Any and all of the above.

There is a brief wikipedia article on "timeout(computing)" that might
help. It provides some real-world examples of differet types of
timeout you might encounter.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos





More information about the Tutor mailing list