Diff
Not logged in

Differences From:

File src/xfer.c part of check-in [edbb332d54] - The xfer mechanism has been completely reworked to better support delta compression and to require fewer round-trips. The wire protocol is roughly the same but is different enough that you will need to recompile before sync will work. by drh on 2007-08-10 02:59:52. [view]

To:

File src/xfer.c part of check-in [50150adeec] - More sync fixes: The previous version was not pulling new branches off of the server. This should fix that. by drh on 2007-08-10 03:50:25. [view]

@@ -192,9 +192,9 @@
 static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){
   Blob content, uuid;
   int size = 0;
 
-  if( db_exists("SELECT 1 FROM sent WHERE rid=%d", rid) ){
+  if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){
      return;
   }
   blob_zero(&uuid);
   if( pUuid==0 ){
@@ -222,9 +222,9 @@
     pXfer->nFileSent++;
   }else{
     pXfer->nDeltaSent++;
   }
-  db_multi_exec("INSERT INTO sent VALUES(%d)", rid);
+  db_multi_exec("INSERT INTO onremote VALUES(%d)", rid);
   blob_reset(&uuid);
 }
 
 /*
@@ -380,9 +380,9 @@
   xfer.mxSend = db_get_int("max-download", 1000000);
 
   db_begin_transaction();
   db_multi_exec(
-     "CREATE TEMP TABLE sent(rid INTEGER PRIMARY KEY);"
+     "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
   );
   while( blob_line(xfer.pIn, &xfer.line) ){
     xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
 
@@ -391,9 +391,9 @@
     **
     ** Accept a file from the client.
     */
     if( blob_eq(&xfer.aToken[0], "file") ){
-      if( !g.okWrite ){
+      if( !isPush ){
         cgi_reset_content();
         @ error not\sauthorized\sto\swrite
         nErr++;
         break;
@@ -414,9 +414,9 @@
     if( blob_eq(&xfer.aToken[0], "gimme")
      && xfer.nToken==2
      && blob_is_uuid(&xfer.aToken[1])
     ){
-      if( g.okRead ){
+      if( isPull ){
         int rid = rid_from_uuid(&xfer.aToken[1], 0);
         if( rid ){
           send_file(&xfer, rid, &xfer.aToken[1], 0);
         }
@@ -430,25 +430,31 @@
     if( xfer.nToken==2
      && blob_eq(&xfer.aToken[0], "igot")
      && blob_is_uuid(&xfer.aToken[1])
     ){
-      if( g.okWrite ){
+      if( isPush ){
         rid_from_uuid(&xfer.aToken[1], 1);
       }
     }else
 
 
     /*   leaf UUID
     **
-    ** Client announces that it has a particular manifest
+    ** Client announces that it has a particular manifest.  If
+    ** the server has children of this leaf, then send those
+    ** children back to the client.  If the server lacks this
+    ** leaf, request it.
     */
     if( xfer.nToken==2
      && blob_eq(&xfer.aToken[0], "leaf")
      && blob_is_uuid(&xfer.aToken[1])
     ){
-      if( g.okRead ){
-        int rid = rid_from_uuid(&xfer.aToken[1], 0);
+      int rid = rid_from_uuid(&xfer.aToken[1], 0);
+      if( isPull && rid ){
         leaf_response(&xfer, rid);
+      }
+      if( isPush && !rid ){
+        content_put(0, blob_str(&xfer.aToken[1]), 0);
       }
     }else
 
     /*    pull  SERVERCODE  PROJECTCODE
@@ -620,37 +626,43 @@
   assert( !g.urlIsFile );          /* This only works for networking */
 
   db_begin_transaction();
   db_multi_exec(
-    "CREATE TEMP TABLE sent(rid INTEGER PRIMARY KEY);"
+    "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
   );
   blobarray_zero(xfer.aToken, count(xfer.aToken));
   blob_zero(&send);
   blob_zero(&recv);
   blob_zero(&xfer.err);
   blob_zero(&xfer.line);
 
+  /*
+  ** Always begin with a clone, pull, or push message
+  */
+  if( cloneFlag ){
+    blob_appendf(&send, "clone\n");
+    pushFlag = 0;
+    pullFlag = 0;
+    nMsg++;
+  }else if( pullFlag ){
+    blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
+    nMsg++;
+  }
+  if( pushFlag ){
+    blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
+    nMsg++;
+  }
+
 
   while( go ){
-
-    /* Generate a request to be sent to the server.
-    ** Always begin with a clone, pull, or push message
+    int newPhantom = 0;
+
+    /* Generate gimme messages for phantoms and leaf messages
+    ** for all leaves.
     */
-
-    if( cloneFlag ){
-      blob_appendf(&send, "clone\n");
-      pushFlag = 0;
-      pullFlag = 0;
-      nMsg++;
-    }else if( pullFlag ){
-      blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
-      nMsg++;
+    if( pullFlag ){
       request_phantoms(&xfer);
       send_leaves(&xfer);
-    }
-    if( pushFlag ){
-      blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
-      nMsg++;
     }
 
     /* Exchange messages with the server */
     nFileSend = xfer.nFileSent + xfer.nDeltaSent;
@@ -662,8 +674,21 @@
     xfer.nDeltaSent = 0;
     xfer.nGimmeSent = 0;
     http_exchange(&send, &recv);
     blob_reset(&send);
+
+    /* Begin constructing the next message (which might never be
+    ** sent) by beginning with the pull or push messages
+    */
+    if( pullFlag ){
+      blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
+      nMsg++;
+    }
+    if( pushFlag ){
+      blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
+      nMsg++;
+    }
+
 
     /* Process the reply that came back from the server */
     while( blob_line(&recv, &xfer.line) ){
       if( blob_buffer(&xfer.line)[0]=='#' ){
@@ -707,8 +732,9 @@
         if( pullFlag ){
           if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0",
                 &xfer.aToken[1]) ){
             content_put(0, blob_str(&xfer.aToken[1]), 0);
+            newPhantom = 1;
           }
         }
       }else
 
@@ -721,11 +747,15 @@
        && blob_eq(&xfer.aToken[0], "leaf")
        && blob_is_uuid(&xfer.aToken[1])
       ){
         nMsg++;
-        if( pushFlag ){
-          int rid = rid_from_uuid(&xfer.aToken[1], 0);
+        int rid = rid_from_uuid(&xfer.aToken[1], 0);
+        if( pushFlag && rid ){
           leaf_response(&xfer, rid);
+        }
+        if( pullFlag && rid==0 ){
+          content_put(0, blob_str(&xfer.aToken[1]), 0);
+          newPhantom = 1;
         }
       }else
 
 
@@ -748,8 +778,10 @@
           db_set("project-code", zPCode);
         }
         cloneFlag = 0;
         pullFlag = 1;
+        blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
+        nMsg++;
       }else
 
       /*   error MESSAGE
       **
@@ -784,12 +816,14 @@
     xfer.nDanglingFile = 0;
     nCycle++;
     go = 0;
 
-    /* If we have received one or more files on this cycle and
-    ** we have one or more phantoms, then go for another round
+    /* If we have received one or more files on this cycle or if
+    ** we have received information that has caused us to create
+    ** new phantoms and we have one or more phantoms, then go for
+    ** another round
     */
-    if(xfer.nFileRcvd+xfer.nDeltaRcvd+xfer.nDanglingFile>0
+    if( (xfer.nFileRcvd+xfer.nDeltaRcvd+xfer.nDanglingFile>0 || newPhantom)
      && db_exists("SELECT 1 FROM phantom")
     ){
       go = 1;
     }