More graceful handling of socket drops. Debugging code for SSK reinsert failure.
diff --git a/infocalypse/devnotes.txt b/infocalypse/devnotes.txt new file mode 100644 --- /dev/null +++ b/infocalypse/devnotes.txt @@ -0,0 +1,12 @@ +djk20090414 + +KNOWN LIMITATIONS: +o Won't handle repositories with multiple heads correctly. + I am reworking the graph rep to fix this. + +FCP BUGS: +o 1208 SSK reinserts of same data fail with code 9. + This breaks fn-reinsert. +o 1208 RemoveRequest kills the FCP connection. + This can cause fn-pull to fail. + It should work if you run it again. diff --git a/infocalypse/fcpconnection.py b/infocalypse/fcpconnection.py --- a/infocalypse/fcpconnection.py +++ b/infocalypse/fcpconnection.py @@ -194,7 +194,7 @@ class NonBlockingSocket(IAsyncSocket): """ data = self.socket.recv(RECV_BLOCK) if not data: - self.close() + #self.close() #ret = False #break return None @@ -763,9 +763,17 @@ class FCPConnection: def closed_handler(self): """ INTERNAL: Callback called by the IAsyncSocket delegate when the socket closes. """ + # REDFLAG: DCI: Remove + def dropping(data): + print "DROPPING %i BYTES OF DATA AFTER CLOSE!" % len(data) self.node_hello = None - + if not self.socket is None: + # REDFLAG: DCI: test! + # Ignore any subsequent data. + self.socket.recv_callback = lambda x:None + self.socket.recv_callback = dropping + # Hmmmm... other info, ok to share this? fake_msg = ('ProtocolError', {'CodeDescription':'Socket closed'}) #print "NOTIFIED: CLOSED" diff --git a/infocalypse/infcmds.py b/infocalypse/infcmds.py --- a/infocalypse/infcmds.py +++ b/infocalypse/infcmds.py @@ -292,7 +292,11 @@ def run_until_quiescent(update_sm, poll_ while update_sm.current_state.name != QUIESCENT: # Poll the FCP Connection. try: - connection.socket.poll() + if not connection.socket.poll(): + print "run_until_quiescent -- poll returned False" + # REDFLAG: jam into quiesent state?, + # CONNECTION_DROPPED state? + break # Indirectly nudge the state machine. update_sm.runner.kick() except socket.error: # Not an IOError until 2.6. diff --git a/infocalypse/requestingbundles.py b/infocalypse/requestingbundles.py --- a/infocalypse/requestingbundles.py +++ b/infocalypse/requestingbundles.py @@ -165,6 +165,7 @@ class RequestingBundles(RetryingRequestL # Catch state machine stalls. if (self.parent.current_state == self and self.is_stalled()): + print "STALLED, BAILING OUT!" self.parent.transition(self.failure_state) # DONT add to pending. Base clase does that. @@ -597,6 +598,7 @@ class RequestingBundles(RetryingRequestL if self.parent.ctx.has_version(latest_version): # Done and done! + print "DONE, UP TO DATE!" self.parent.transition(self.success_state) return diff --git a/infocalypse/topkey.py b/infocalypse/topkey.py --- a/infocalypse/topkey.py +++ b/infocalypse/topkey.py @@ -40,6 +40,8 @@ from binascii import hexlify, unhexlify from chk import CHK_SIZE, bytes_to_chk, chk_to_bytes +from fcpconnection import sha1_hexdigest + MAJOR_VERSION = '1' MINOR_VERSION = '00' @@ -141,4 +143,7 @@ def dump_top_key_tuple(top_key_tuple, ou out_func(" latest_rev: %s\n" % update[2]) for index, chk in enumerate(update[3]): out_func(" CHK[%i]:%s\n" % (index, chk)) + out_func("binary rep sha1:\n0x00:%s\n0xff:%s\n" % + (sha1_hexdigest(top_key_tuple_to_bytes(top_key_tuple, 0)), + sha1_hexdigest(top_key_tuple_to_bytes(top_key_tuple, 0xff)))) out_func("---\n")