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")