Commits

Jakub Gustak committed d3115fb

node checks md5 before sending to client, if wrong - sends BItemCmd;
ctrl supports GetCmd - rsponse is RetrCmd; supports BItemCmd - removes from cache
nrp tries to reget when md5 check failed

Comments (0)

Files changed (4)

 
 from protocol import Command, PutCmd, GetCmd, SendCmd, LsCmd, RmCmd, ItemCmd, \
         FailedCmd, DoneCmd, EhloCmd, PdoneCmd, ByeCmd, ExpectCmd, RetrCmd, \
-        RmfCmd, LsfCmd, FileCmd
+        RmfCmd, LsfCmd, FileCmd, BItemCmd
 
 NODES = []
 
             assert self.node
             f.parts[item.chunk].add_node(self.node)
 
+        elif cmd.valid(BItemCmd):
+            bitem = cmd.parse(BItemCmd)
+            try:
+                f = self.factory.cache[bitem.filename]
+                assert self.node
+                f.parts[bitem.chunk].del_node(self.node)
+
+            except KeyError:
+                #wtf
+                pass
+
+            self.sendCmd(RmCmd(bitem.id, bitem.filename,
+                bitem.chunk, bitem.chunks))
+
         elif cmd.valid(PutCmd):
             if len(NODES) < MINNODES:
                 self.sendCmd('MINNODES')
             self.sendCmd(SendCmd(put.id, put.filename, put.chunk, put.chunks,
                                  host, port))
 
+        elif cmd.valid(GetCmd):
+            if len(NODES) < MINNODES:
+                self.sendCmd('MINNODES')
+                return
+
+            get = cmd.parse(GetCmd)
+            try:
+                f = self.factory.cache[get.filename] 
+                p = f.parts[get.chunk]
+            except KeyError, IndexError:
+                self.sendCmd(FailedCmd())
+                return
+
+            #choose your destiny
+            host, port, proto = p.rand_node()
+            self.sendCmd(RetrCmd(p.id, f.filename, p.chunk, f.chunks,
+                                 host, port))
+
         elif cmd.valid(LsCmd):
             ls = cmd.parse(LsCmd)
             try:
 from twisted.protocols import basic
 from twisted.application import service
 from protocol import Command, PutCmd, GetCmd, ReadyCmd, SendCmd, LsCmd, RmCmd,\
-        ItemCmd, EhloCmd, PdoneCmd, ByeCmd, ExpectCmd, FailedCmd
+        ItemCmd, BItemCmd, EhloCmd, PdoneCmd, ByeCmd, ExpectCmd, FailedCmd
 
 import os, re, time, sys, hashlib
 from ctrl import RS, DATA_LEN, CODE_LEN, CHUNK_SIZE, ChecksumError
 
                 self.file.close()
 
-                if get.id != hashlib.md5(decoded).hexdigest():
+                if get.id != hashlib.md5(raw).hexdigest():
+                    self.factory.ctrl.sendCmd(
+                            BItemCmd(get.id, get.filename, get.chunk, get.chunks))
                     self.transport.loseConnection()
-                    # XXX self.factory.ctrl.sendCmd( "FAILED" )
 
                 self.cmd = get
 
         if cmd.valid(RetrCmd):
             retr = cmd.parse(RetrCmd)
 
-            self.f.chunks = range(retr.chunks) # XXX not here, hack
+            if not self.f.chunks:
+                self.f.chunks = range(retr.chunks) # XXX not here, hack
+
             self.chunkd[retr.id] = retr
             
             reactor.connectTCP(retr.host, retr.port,
                     clientGTPFactory(retr.id, self.chunkd[retr.id], self))
 
         else:
-            print "No such file"
+            print line, "No such file"
             self.transport.loseConnection()
 
 
         try:
             self.ctrl.f.append_chunk(self.item.chunk, self._buff, self.id)
         except ChecksumError:
-            print "chunk", self.id, "error"
+            print "chunk failed:", self.item.filename, self.id
+            self.ctrl.sendCmd(GetCmd(id=self.item.id, filename=self.item.filename,
+                chunk=self.item.chunk, chunks=self.item.chunks))
+            return
 
         self.ctrl.chunk_release(self.id)
 
 
         #XXX: check this id
         if id != hashlib.md5(decoded).hexdigest():
-            print id, hashlib.md5(decoded).hexdigest()
             raise ChecksumError
 
         self.chunks[chunkid] = decoded
 class ItemCmd(ChunkCmd):
     token = 'ITEM'
 
+class BItemCmd(ChunkCmd):
+    token = 'BITEM'
+
 class PutCmd(ChunkCmd):
     token = 'PUT'
 
 class SendCmd(ChunkCmd):
     """Send command
 
-    SEND hash_id filename chunk_number all_chunks to_node"""
+    SEND id filename chunk chunks to_node"""
     token = 'SEND'
 
     def __init__(self, id, filename, chunk, chunks, host, port):