summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Edwards <joeledwards@gmail.com>2013-12-04 03:01:39 -0700
committerJoel Edwards <joeledwards@gmail.com>2013-12-11 07:37:55 -0700
commitfd57bd0466040238cd18cf2068b739cce36e9d40 (patch)
treedc9cf98309e7311e2ba13148e6f92d3a2b9d0ada
parent6ee490ffd6ae63e8898333e28f449836b35c4c70 (diff)
downloadpexpect-fd57bd0466040238cd18cf2068b739cce36e9d40.tar.gz
Cleaned up prompt synchronization
-rw-r--r--pexpect/pxssh.py60
1 files changed, 36 insertions, 24 deletions
diff --git a/pexpect/pxssh.py b/pexpect/pxssh.py
index 9fd4c3d..65f2c57 100644
--- a/pexpect/pxssh.py
+++ b/pexpect/pxssh.py
@@ -140,60 +140,72 @@ class pxssh (spawn):
current[j] = min(add, delete, change)
return current[n]
- # JDE: method to facilitate using comm timeouts rather than sleeps to
- # perform synchronization
- def try_read_prompt(self, initial_timeout, interval_timeout, total_timeout):
- done = False
+ def try_read_prompt(self, timeout_multiplier):
+
+ '''This facilitates using communication timeouts to perform
+ synchronization as quickly as possible, while supporting high latency
+ connections with a tunable worst case performance. Fast connections
+ should be read almost immediately. Worst case performance for this
+ method is timeout_multiplier * 3 seconds.
+ '''
+
+ # maximum time allowed to read the first response
+ first_char_timeout = timeout_multiplier * 0.5
+
+ # maximum time allowed between subsequent characters
+ inter_char_timeout = timeout_multiplier * 0.1
+
+ # maximum time for reading the entire prompt
+ total_timeout = timeout_multiplier * 3.0
+
prompt = ''
begin = time.time()
- expired = 0
- # Set time to wait for the first character
- timeout = initial_timeout
- while (not done) and (expired < total_timeout):
+ expired = 0.0
+ timeout = first_char_timeout
+
+ while expired < total_timeout:
try:
c = self.read_nonblocking(size=1, timeout=timeout)
prompt += c # append acquired content
expired = time.time() - begin # updated total time expired
- timeout = interval_timeout # Set time to wait between characters
+ timeout = inter_char_timeout
except TIMEOUT:
+ # when the host has finished sending its response, the
+ # inter_char_timeout will drop us out of the loop quickly
expired = total_timeout
+
return prompt
- def sync_original_prompt (self, sync_multiplier=1):
+ def sync_original_prompt (self, sync_multiplier=1.0):
'''This attempts to find the prompt. Basically, press enter and record
the response; press enter again and record the response; if the two
- responses are similar then assume we are at the original prompt. This
- is a slow function. It can take over 10 seconds. '''
- # Timeouts which can be adjusted by a multiplier supplied by the user
- # in the event of stations with very poor connections
- # Worst case (with default multiplier) should be 12 seconds in the event
- # that no response is ever received
- initial_timeout = sync_multiplier * 0.5
- interval_timeout = sync_multiplier * 0.1
- total_timeout = sync_multiplier * 3
+ responses are similar then assume we are at the original prompt.
+ This can be a slow function. Worst case with the default sync_multiplier
+ can take 12 seconds. Low latency connections are more likely to fail
+ with a low sync_multiplier. Best case sync time gets worse with a
+ high sync multiplier (500 ms with default). '''
# All of these timing pace values are magic.
# I came up with these based on what seemed reliable for
# connecting to a heavily loaded machine I have.
self.sendline()
time.sleep(0.1)
- # If latency is worse than these values then this will fail.
try:
# Clear the buffer before getting the prompt.
- self.try_read_prompt(initial_timeout, interval_timeout, total_timeout)
+ self.try_read_prompt(sync_multiplier)
except TIMEOUT:
pass
self.sendline()
- x = self.try_read_prompt(initial_timeout, interval_timeout, total_timeout)
+ x = self.try_read_prompt(sync_multiplier)
self.sendline()
- a = self.try_read_prompt(initial_timeout, interval_timeout, total_timeout)
+ a = self.try_read_prompt(sync_multiplier)
self.sendline()
- b = self.try_read_prompt(initial_timeout, interval_timeout, total_timeout)
+ b = self.try_read_prompt(sync_multiplier)
ld = self.levenshtein_distance(a,b)
len_a = len(a)